在 GCD 文档中很清楚,要将工作提交到主队列,您需要在
NSApplication
(或 UIApplication
)内工作,或者调用 dispatch_main()
充当某种运行循环。但是,我需要做什么来设置全局并发队列吗?
基本上我要问的是:如果我编写一个简单的 C 程序,在我开始
dispatch_get_global_queue()
并开始让它工作之前,我是否需要执行任何特殊设置?
你不需要调用任何东西来启动调度程序,但是你不能退出主线程,否则即使队列上有未完成的工作,你的程序也会退出。您可以使用信号量来阻止主线程退出:
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;
}
代替信号量,有一种概念上更简单但不太实用的方法,即调用 sleep,或者在循环中计数到一个巨大的数字(确保编译器不会优化它),或者循环直到一个变量(最初设置为 false,当处理完成时设置为 true)为 true(称为 busy-wait)。其中每一个都有严重的缺陷,并且远不如信号量更好。
您还可以通过创建一个串行队列并对其调用几次dispatch_async,然后调用dispatch_sync,然后退出程序来测试它。
有充分的理由调用dispatch_main或启动运行循环,但请注意发送到除主队列之外的任何队列的内容可以启动在dispatch_main的运行循环启动之前。
由于dispatch_main()永远不会返回,这也会阻止你的main函数到达它的返回值。
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);
}
要编译它,请使用:
clang -Wall -Werror -fblocks -L/usr/local/lib -I/usr/local/include -o test test.c