2011-12-03 2 views
7

GCD 문서에서 메인 대기열에 작업을 제출하려면 NSApplication (또는 UIApplication) 내에서 작업하거나 dispatch_main()을 호출하여 작업해야합니다. 일종의 실행 루프. 그러나 글로벌 동시 대기열을 설정하려면 아무 것도해야합니까?응용 프로그램 또는 runloop 외부에서 Grand Central Dispatch 사용하기

기본적으로 내가 묻는 것은 : 단순한 C 프로그램을 작성하면 dispatch_get_global_queue()로 가서 작동시키기 전에 특별한 설정을 수행해야합니까?

답변

4

아니요, 추가 설정이 필요하지 않습니다. 그러나 dispatch_main()을 호출하여 GCD 디스패처를 시작해야합니다.
dispatch_main()이 반환하지 않으므로 주 함수가 반환되지 않습니다. (http://wiki.freebsd.org/GCD 기준) GCD & 글로벌 큐를 사용하는 최소한의 C 프로그램에 대한

예 :

clang -Wall -Werror -fblocks -L/usr/local/lib -I/usr/local/include -o test test.c 
+1

dispatch_main 호출이 필요하지 않습니다. 예를 들어 10 초간 수면으로 바꾸면 5 초 타이머가 계속 트리거됩니다. – Stripes

7

당신은 호출 할 필요는 없다 :

#include <dispatch/dispatch.h> 
#include <err.h> 
#include <stdio.h> 
#include <stdlib.h> 

int main(int argc, char *argv[]) 
{ 
    dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 
    dispatch_time_t dispatchTime = dispatch_time(DISPATCH_TIME_NOW, 5LL * NSEC_PER_SEC); 
    dispatch_after(dispatchTime, globalQueue, ^{ 
     printf("Dispatched on global queue\n"); 
     exit(0); 
    }); 
    dispatch_main(); 
    return (0); 
} 

이 사용을 컴파일하려면 디스패처를 시작할 수있는 아무 것도 없지만 대기열에서 불완전한 작업이있는 경우 주 스레드를 종료 할 수 없거나 프로그램이 종료됩니다. 아무튼 (

대신 세마포어의
int main() { 
    __block int count = 10; 
    dispatch_semaphore_t done = dispatch_semaphore_create(0); 
    dispatch_time_t naptime; 

    // timeout after 5 seconds 
    naptime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)5E9); 
    // no timeout 
    //naptime = dispatch_time(DISPATCH_TIME_FOREVER, 0); 

    // schedule some work 
    dispatch_async(
     dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), 
     ^{ 
      dispatch_apply(count, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW,0), 
       ^(size_t i){ 
        //... 
        // note: potential race condition on count. 
        // Synchronization left as an exercise. 
        if (--count == 0) { 
         dispatch_semaphore_signal(done); 
        } 
       } 
      ); 
     } 
    ); 

    if (dispatch_semaphore_wait(done, naptime)) { 
     // processing didn't complete in allotted time 
     //... 
    } 
dispatch_release(done); 
    return 0; 
} 

는, 잠을 호출하거나 루프에서 엄청난 수에 계산의 개념적으로 쉽게 미만 사용 가능한 방법이 확실 컴파일러를 만들 : 당신은 사용하여 세마포어에 의해 종료에서 메인 스레드를 방지 할 수 있습니다 최적화하지 않거나 변수가 처리 될 때 true로 설정 될 때까지 루핑됩니다 (busy-wait). 이들 각각은 심각한 결함이 있으며 세마포보다 덜 바람직합니다.

직렬 대기열을 만들고이를 몇 번 호출 한 다음 dispatch_sync를 호출 한 다음 프로그램을 종료하여 테스트 할 수도 있습니다.

는 전에 시작 dispatch_main 할 수있는 runloop을 을 시작할 수 있습니다 주요 큐를 제외하고 당신이 어떤 큐에 보내 알고 일을 dispatch_main 호출하거나 실행 루프를 시작하지만 할 좋은 이유가 있습니다.

+0

이것은'libdispatch' 기반 프로그램을 정상적으로 종료하는 방법에 대한 좋은 대답입니다. " 나중에 참고할 수 있습니다. – Eonil

+1

'대기열 작업'을 수동으로 계산해야합니다. 모든 대기열이 비었을 때 dispatch_main()을 끝내는 방법이 있습니까? 그리고 dispatch_source가 할당되지 않았습니까? NSRunLoop과 유사 (AFAIK가 종료됩니다. 실행해야 할 것이 아무것도없는 경우 실행합니다). – hnh

+1

아니, 내가 생각할 수있는 가장 가까운 것은 모든 dispatch_group_async를 사용하여 작업을 시작한 다음 exit를 트리거하기 위해 dispatch_group_notify를 사용하는 것이지만 일반 또는 자동이 아닙니다. dealloc 핸들러를 대기열에 추가하고 해제하는 모든 작업을 시작하는 것이 좋겠지 만 불법적 인 부활 문제가 있습니다. 귀하의 앱은 본질적으로 완전성을 인식하는 방법을 알아야 할 필요가 있다고 생각합니다. 파견은 해당 메시지를 전달하는 데 도움이 될 수 있지만 메시지를 생성 할 수는 없습니다. – Stripes

관련 문제