为什么GCD不起作用?

时间:2018-03-30 11:00:38

标签: ios grand-central-dispatch deadlock

为什么下载GCD不起作用?所有子线程都在__ulock_wait暂停,但没有死锁。

dispatch_queue_t queue = dispatch_queue_create("test_gcd_queue", DISPATCH_QUEUE_CONCURRENT);
for (int i = 0; i < 10000; i++)
{
    dispatch_async(queue, ^{
        dispatch_sync(queue, ^{
            NSLog(@"---- gcd: %d", i);
        });
    });
    //NSLog(@"---------- async over: %d", i);  //Have this, OK.
}
NSLog(@"-------------------- cycle over");

1 个答案:

答案 0 :(得分:2)

这不起作用,因为内部dispath_sync()使用它运行的相同队列。它的块必须等到队列中的最后一项执行。由于当前代码在队列中,这是一个死锁,因为dispatch_sync()等待其周围块的终止。

在并发队列上,如果您启动的任务多于队列中的线程,则可能会产生相同的效果。每个循环迭代需要两个线程。如果在执行期间的某个时刻所有线程都被dispatch_sync()开头的异步任务阻塞,则没有同步任务有机会启动,因此没有异步任务有机会完成。

代码中的循环将非常快速地创建大量异步任务。由于每个任务的启动开销,它们会堵塞队列。因此,只有少数同步任务有机会启动并让异步任务完成。

如果要在外环中插入一个小延迟(例如1ms),应该减轻甚至消除这种堵塞。