3

저는 iPhone 개발의 최신 버전이며 멀티 스레딩을위한 GCD 개념을 사용합니다.dispatch_queue_t가 직렬 큐인 경우 멀티 태스크 개념에 왜 존재합니까?

'dispatch_queue_t'는 직렬 대기열을 만들고 직렬 대기열은 한 번에 하나의 작업 만 실행한다는 것을 읽었습니다. GCD는 여러 작업을 동시에 실행하고 직렬 대기열이 존재하는 이유는 무엇입니까?

예를 들어 2 가지 작업을 수행하고 싶습니다. 작업 A와 작업 B.이 작업을 모두 실행하기 위해 하나의 직렬 대기열을 만듭니다. 나는 메인 큐에서 이것을하고있다.

dispatch_queue_t my_serial_queue = dispatch_queue_create("queue_identifier", 0); 

    dispatch_sync(my_serial_queue, ^{ 
     NSLog(@"Task 1"); 
    }); 

    dispatch_sync(my_serial_queue, ^{ 
     NSLog(@"Task 2"); 
    }); 

규칙에 따라 경찰, 이제 모두가 시리얼 큐 즉, 작업 A가 먼저 다음 작업 A를 완료 한 후, 작업 B 실행되는대로 작업이 순차적으로 실행됩니다 : 여기에 내가 뭐하는 거지 코드입니다 실행됩니다. 또한 로그에서 동일한 출력을 제공합니다.

내 질문은, 두 작업을 동시에 실행하려면 어떻게합니까? 이 질문의 대답이 작업 B의 다른 직렬 대기열을 만드는 것이라면 코드는 다음과 같이 구성되어야합니다.

dispatch_queue_t my_serial_queue_1 = dispatch_queue_create("queue_identifier_1", 0); 
dispatch_queue_t my_serial_queue_2 = dispatch_queue_create("queue_identifier_2", 0); 


    dispatch_sync(my_serial_queue_1, ^{ 
     NSLog(@"Task 1"); 
    }); 

    dispatch_sync(my_serial_queue_2, ^{ 
     NSLog(@"Task 2"); 
    }); 

동일한 출력을 얻고 있습니다. 이유는 'dispatch_async'호출 대신 'dispatch_sync'호출을 사용하고 있습니다. 그러나 두 작업을 다른 대기열에서 실행 중이므로 동시에 실행하면 안됩니까? 그렇지 않다면 다른 큐를 만들어야하는 이유는 무엇입니까? 두 작업을 동시에 실행하기 위해 'dispatch_async'호출에 의해 같은 큐를 사용했을 수도 있습니다.

내 멀티 태스킹 응용 프로그램의 구조를 설계하기 전에 미래에 나에게 더 나은 지침이 될 것이므로이 질문에 대한 답이 정말 필요합니다.

감사합니다. 미리 감사드립니다.

답변

4

당신이 dispatch_sync를 사용하고 있기 때문에 당신의 혼란은 거의 완전히 있습니다. dispatch_sync는 이 아니며 동시 실행을위한 도구 인이며 일시적으로 안전을 제한하기위한 도구입니다.

일단 dispatch_async를 사용하면 둘 이상의 대기열을 사용하거나 동시 대기열을 사용하여 동시성을 확보 할 수 있습니다. 이 컨텍스트에서 직렬 대기열을 사용하는 목적은 제어입니다.이 작업은 동시에 수행됩니다. 결국, 동시에 실행되는 블록의 두 행에서 '공유'자유 의지 때문에,

__block void *shared = NULL; 
for (;;) { 
    dispatch_async(aConcurrentDispatchQueue, ^{ 
     shared = malloc(128); 
     free(shared); 
    } 
} 

이 충돌합니다 :

는 다음과 같은 매우 바보 같은 예를 생각해 보자. 이것은 고의적 인 예제이지만 실제로는 거의 모든 공유 가변 상태을 동시에 변경하면 안됩니다. 직렬 대기열을 사용하면 그렇게 할 수 있습니다.

요약하기 :

  • 당신의 블록 작업이 진정으로 독립적이고 스레드 안전하고, 순수하게 계산이다

    가서 당신이 논리적으로 독립적 인 작업 각이있을 때 동시 큐
  • 에 dispatch_async 사용 각각의 작업에 대해 직렬 대기열을 사용하십시오.
  • 공유 가변 상태에 액세스하는 작업을 할 때 직렬 대기열의 dispatch_sync()에있는 블록과 동시 대기열에있는 나머지 작업을 수행하십시오
  • 당신이
+1

@ Catfish_Man : 간단히 말해서 내가 말한 2 가지 작업을 완전히 동시에 수행하려면 직렬 대기열에서 'dispatch_async'를 사용하거나 (2) 두 작업에 대해 2 개의 동시 대기열을 생성해야합니다. 'dispatch_queue_t'에 의해 2 개의 큐를 생성하는 것이 아니라 ('dispatch_queue_t'가 직렬 큐를 생성하기 때문에). – NSPratik

+0

@ Catfish_Man :이 두 가지 작업이 완전히 독립적이라고 가정합니다. – NSPratik

+0

하나의 동시 대기열 또는 두 개의 연속 대기열. 직렬 대기열은 모든 항목을 순서 지정하지만 다른 모든 대기열과 동시에 수행합니다. 동시 대기열은 전혀 대기열을 지정하지 않습니다. –

1

'dispatch_queue_t'당신이 끝날 때까지 기다릴 필요 여부에 따라, 메인 큐에 UI 관련 작업, dispatch_async 또는 dispatch_sync을해야 할 때 아무것도 만들지 않습니다. dispatch_queue_t 이며, 디스패치 대기열은 직렬 또는 동시입니다.

dispatch_queue_create에는 두 개의 매개 변수가 있습니다. 두 x 째 매개 변수는 작성하는 대기열이 직렬 또는 동시 대기열인지 여부를 결정합니다. 그러나 일반적으로 동시 대기열을 직접 작성하지는 않지만 기존의 세 가지 동시 대기열 중 하나를 사용하십시오.

dispatch_sync는 큐에 블록 을 전달하고 블록이 완료 될 때까지 대기합니다.. 이것이 매우 많은 동시성을 제한한다는 것이 명백해야합니다. 거의 항상 dispatch_async를 사용해야합니다.

순차적 대기열은 한 번에 하나의 블록 만 실행할 수 있습니다. 이것이 매우 많은 동시성을 제한한다는 것이 명백해야합니다. 연속 대기열은 여러 블록을 차례로 수행해야 할 때 유용하며 다른 대기열의 블록과 동시에 실행할 수 있습니다.

따라서 프로세서를 최대로 사용하려면 동시 대기열에서 dispatch_async를 사용하십시오. 또한 동시 대기열을 두 개 이상 작성할 필요가 없습니다. 동시 다. 임의의 수의 블록을 동시에 실행할 수 있습니다.

+0

@ gnasher729 : 귀하의 성명서 : "순차적 인 큐는 여러 블록을 차례로 수행해야 할 때 여전히 유용하며 다른 큐의 블록과 동시에 실행할 수 있습니다." 실용적으로하기 위해 2 개의 직렬 대기열을 만들어 데모를 만들었습니다. 그러나 이러한 대기열은 동시에 실행되지 않습니다. 큐 B의 블록은 A의 모든 블록이 실행을 완료 할 때까지 실행되지 않습니다. 심지어 두 큐를 동시에 만들려고 했는데도 여전히 같은 결과를 얻었습니다. 왜 dispatch_async 호출을 만들 때까지 해당 큐를 동시에 실행할 수 없습니까? (심지어 동시 대기열을 생성합니다) – NSPratik

+1

dispatch_sync (첫 번째 블록), dispatch_sync (두 번째 블록)를 사용하는 경우 첫 번째 블록이 완료 될 때까지 기다리지 않고 dispatch_sync (두 번째 블록)는 첫 번째 블록이 완료된 후에 만 ​​실행됩니다. 그렇게 사용하면 대기열이하는 일은별로 중요하지 않습니다. – gnasher729