Using Grand Central Dispatch outside the app or runloop

In the GCD documentation, it’s clear that to send work in the main, you need to either work in NSApplication (or UIApplication) or call dispatch_main () to act as a sorting loop. However, do I need to do something to configure the global parallel queue?

Basically I ask: if I am writing a simple simple program in C, do I need to do any special setup before I dispatch dispatch_get_global_queue () and start giving it work?

+7
source share
2 answers

No, you do not need additional configuration. But you need to call dispatch_main () to start the GCD manager.
Since dispatch_main () never returns, this will also prevent your main function from returning to it.

Example for a minimal C program that uses a GCD and a global queue (based on http://wiki.freebsd.org/GCD ):

#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); } 

To compile this, use:

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

You do not need to call anything to start the dispatcher, but you cannot exit the main thread or your program will exit if in case of incomplete work in the queues. You can prevent the main thread from exiting using semaphores:

 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; } 

Instead of semaphores, there is a conceptually simpler, but less useful way to call sleep or count to a huge number in a loop (make sure the compiler does not optimize it) or loop to a variable (initially set to false, set to true when processing is completed) is true (known as busy-wait ). Each of them has serious flaws and is much less preferable than a semaphore.

You can also test it by running a sequential queue and calling dispatch_async several times, then dispatch_sync, and then exit the program.

There are good reasons to call dispatch_main or start a run loop, but keep in mind the things you send to any queue, except that the main queue can start before runloop is started to send the tram.

+7
source

All Articles