0

以此为参考,以下示例 {could not} / {would not} 是否有任何理由导致 GCD 线程池仅在主线程上运行?

int main()
{
    dispatch_queue_t myQueue = dispatch_queue_create("myQ",NULL); // create serial queue

    //
    dispatch_sync(myQueue, ^{/*some simple block*/});
    ....
    dispatch_sync(myQueue, ^{/*some simple block*/});
} 

我的理解是,GCD 会尽可能地优化性能,将块(如果有好处)交给任何可用的线程。然而,在 xcode 中监视这一点表明这可能只在主线程上运行。直到调度调用变为async使用第二个线程。

我只想了解何时/为什么可能会或可能不会调用第二个线程。在此之前,我假设总是会调用第二个线程。

4

1 回答 1

0

您正在使用 dispatch_sync 分派块。dispatch_sync 一直等到块执行完毕。因此,您所做的事情毫无意义,除非您将该串行队列用于同步目的。不可能有并发。相反,如果已经在串行队列上执行了代码并且可能已经分派了块,那么您的主线程将不得不等到正在运行的块和所有进一步分派的块完成,然后再等到您的块完成.

如果您调用 dispatch_async,那么这两个块将被分派到串行队列,将一个接一个地执行(使用一个 CPU),而您的主线程将继续使用另一个 CPU 做其他事情。

如果您将 dispatch_async 调用到并发队列,那么这两个块将并行执行,而您的主线程可以执行其他操作,最多使用三个 CPU。

现在您的代码将“正式”在另一个线程上运行您的块,而主线程被阻止。由于线程切换很昂贵,因此尽可能避免使用它们。所以dispatch_sync到一个串行队列会检查队列是否为空,如果为空则阻塞队列调度,在调用线程上执行阻塞,然后解除阻塞队列。行为与分派块完全相同,但执行速度更快。

于 2015-02-18T22:31:56.343 回答