[objective-c] dispatch_async 이해하기


Answers

모든 DISPATCH_QUEUE_PRIORITY_X 대기열은 동시 대기열 (즉, 여러 작업을 동시에 실행할 수 있음)이며, 주어진 대기열 내의 작업이 "선입 선출 (FIFO in first out)"순서로 실행되기 시작한다는 점에서 FIFO입니다. 이것은 직렬 대기열 인 dispatch_get_main_queue ()의 기본 대기열과 비교됩니다 (작업이 실행되고 수신 된 순서대로 실행이 완료 됨).

따라서 DISPATCH_QUEUE_PRIORITY_DEFAULT에 1000 개의 dispatch_async () 블록을 보내면 해당 작업은 큐에 보낸 순서대로 실행되기 시작합니다. HIGH, LOW 및 BACKGROUND 대기열에 대해서도 마찬가지입니다. 이러한 대기열에 보내는 모든 것은 백그라운드에서 대체 스레드에서 실행되며 기본 응용 프로그램 스레드는 사용하지 않습니다. 따라서 이러한 대기열은 백그라운드 다운로드, 압축, 계산 등과 같은 작업을 실행하는 데 적합합니다.

실행 순서는 큐 단위로 FIFO입니다. 따라서 1000 개의 dispatch_async () 작업을 4 개의 다른 동시 대기열로 보내고 균등하게 분할하여 BACKGROUND, LOW, DEFAULT 및 HIGH로 순서대로 전송하면 (예 : HIGH 대기열에서 마지막 250 개의 작업을 예약), 시스템이 가능한 한 빨리 CPU에 도달해야 함을 암시하기 때문에 시작하는 첫 번째 작업은 해당 HIGH 대기열에있게됩니다.

또한 "순서대로 실행을 시작합니다."라고 말하지만 동시 대기열에서는 각 작업의 시간 길이에 따라 순서대로 실행이 완료되지 않을 수도 있습니다.

Apple 당 :

https://developer.apple.com/library/content/documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationQueues/OperationQueues.html

동시 디스패치 대기열은 병렬로 실행할 수있는 여러 작업이있는 경우에 유용합니다. 동시 대기열은 선입 선출 순서로 작업을 대기열에서 제외한다는 점에서 여전히 대기열입니다. 그러나 동시 큐는 이전 태스크가 완료되기 전에 추가 태스크를 큐에서 제거 할 수 있습니다. 특정 순간에 동시 대기열에 의해 실행되는 실제 작업 수는 가변적이며 응용 프로그램의 조건이 변경되면 동적으로 변경 될 수 있습니다. 사용 가능한 코어 수, 다른 프로세스가 수행하는 작업량, 다른 직렬 작업 대기열의 작업 수 및 우선 순위 등 동시 대기열에 의해 실행되는 작업 수에 영향을주는 요소가 많습니다.

기본적으로 1000 개의 dispatch_async () 블록을 DEFAULT, HIGH, LOW 또는 BACKGROUND 대기열로 보내면 모든 순서대로 실행됩니다. 그러나 더 짧은 작업은 긴 작업보다 먼저 완료 될 수 있습니다. 그 이유는 사용 가능한 CPU 코어가 있거나 현재 대기열 작업이 계산적으로 비 집중적 인 작업을 수행하고있는 경우입니다 (따라서 코어 수에 관계없이 추가 작업을 병렬로 처리 할 수 ​​있다고 시스템이 판단하게 만듭니다).

동시성의 수준은 시스템에 의해 전적으로 처리되며 시스템로드 및 기타 내부적으로 결정된 요소를 기반으로합니다. 이것은 Grand Central Dispatch (dispatch_async () 시스템)의 아름다움입니다. 작업 단위를 코드 블록으로 만들고, 선택한 큐를 기준으로 작업 단위를 우선 순위로 설정하고 나머지는 시스템에서 처리하도록합니다.

그래서 위의 질문에 대답하십시오 : 당신은 부분적으로 정확합니다. 지정된 우선 순위 수준에서 전역 동시 대기열에서 동시 작업을 수행하도록 "코드 요청"을합니다. 블록의 코드는 백그라운드에서 실행될 것이고 추가 (비슷한) 코드는 시스템의 가용 자원 평가에 따라 잠재적으로 병렬로 실행될 것입니다.

반면에 "main"대기열 (dispatch_get_main_queue ())은 직렬 대기열입니다 (병행하지 않음). 기본 대기열로 보낸 작업은 항상 순서대로 실행되며 항상 순서대로 완료됩니다. 이러한 작업은 UI 스레드에서 실행되므로 진행 메시지, 완료 알림 등으로 UI를 업데이트하는 데 적합합니다.

Question

이 코드를 둘러싼 질문이 있습니다.

dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    NSData* data = [NSData dataWithContentsOfURL: 
      kLatestKivaLoansURL];
    [self performSelectorOnMainThread:@selector(fetchedData:) 
      withObject:data waitUntilDone:YES];
});

이 코드의 첫 번째 매개 변수는 다음과 같습니다.

dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) 

주어진 우선 순위 레벨의 전역 동시 대기열을 반환한다는 정의 자체가있는 글로벌 대기열에서 직렬 작업을 수행하도록이 코드에 요청하고 있습니까?

메인 큐를 통해 dispatch_get_global_queue 를 사용하면 어떤 이점이 있습니까?

나는 혼란 스럽다. 이 점을 더 잘 이해하도록 도와주세요.