iOS GCD队列阻塞问题

发布于 2022-09-06 09:21:24 字数 416 浏览 23 评论 0

代码1

dispatch_queue_t mainQueue = dispatch_get_main_queue();
dispatch_sync(mainQueue, ^{
    NSLog(@"为啥堵塞");
});

代码2

dispatch_queue_t queue = dispatch_queue_create("abc", DISPATCH_QUEUE_SERIAL);
dispatch_sync(queue, ^{
    NSLog(@"为啥不堵塞");
});

如上,两段代码,都运行在主线程中,mainQueue也是串行队列,为什么代码1会造成线程阻塞,而代码2不会阻塞?或者说代码2不会阻塞大家可能都了解,为什么在主队列调用dispatch_sync就会阻塞?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

神经大条 2022-09-13 09:21:24
  • 1

    App:主线程,你过来,给你个任务,任务完成后再走
    主线程:什么任务?
    App:你去那边打印机上,打印个东西,但是你不能离开这里,完成后才能走
    主线程:……
    
  • 2

    App:主线程,你过来,给你个任务,任务完成后再走
    主线程:什么任务?
    App:你叫 **abc** 去那边打印机上,打印个东西,但是你不能离开这里,完成后才能走
    主线程:**abc**,快去打印个东西,现在就要!
ゃ人海孤独症 2022-09-13 09:21:24

循环等待。你在主线程同步派发一个任务,那主线程就要等这个任务执行完才继续执行。而你又把任务派发在主线程,主线程现在在等待这个完成继续执行,这个任务又在等待主线程空闲来执行。

提笔落墨 2022-09-13 09:21:24

第一个是阻塞mainQueue, 然后让mainQueue去把block里面的东西加到mainQueue中去
第二个是阻塞dispatch_queue_create("abc", DISPATCH_QUEUE_SERIAL), 然后让mainQueue把block里面的东西加到dispatch_queue_create("abc", DISPATCH_QUEUE_SERIAL)中去.

无所的.畏惧 2022-09-13 09:21:24

为什么1会阻塞?因为1是主线程,runloop会时时监听和更新UI,你这里给它安排一个同步sync肯定阻塞,应该用异步async。
为什么2不会阻塞?不是不会阻塞,只是不会阻塞主线程,因为你这里新建的一个子线程,如果你在这个子线程里写个while(TRUE),然后再用这个子线程来同步(sync)一个操作,你看看会不会阻塞这个子线程。

空城仅有旧梦在 2022-09-13 09:21:24

串行并行是对队列而言的,串行队列要对加入其中的任务执行过程前面的执行完后面的任务才能执行。
代码1只有一个主队列,而代码2有两个队列。代码1的主队列也就要求了任务必须是执行完

任务A
dispatch_queue_t mainQueue = dispatch_get_main_queue();
dispatch_sync(mainQueue, ^{
});

这一句才能执行其他的,但是你这个又是同步,所以必须要先执行

 任务B
 NSLog(@"为啥堵塞");

才能执行其他的,这样的逻辑很明显会使当前的主队列阻塞。

再看第二个,

任务A
dispatch_queue_t queue = dispatch_queue_create("abc", DISPATCH_QUEUE_SERIAL);
dispatch_sync(queue, ^{
});

任务A是主队列

NSLog(@"为啥不堵塞");

这句是在abc串行队列,这都是两个队列,所以不要求任务A执行完再执行任务B,由于是同步,所以是先执行任务A的一部分,再去执行任务B的一部分,最后再去执行任务A,只不过这个过程都是主线程执行而已。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文