You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Objective-C使用dispatch_semaphore时出现主线程死锁问题

死锁原因

你提交的代码当前运行在主线程上下文,触发死锁的流程如下:

  1. 主线程执行dispatch_semaphore_create(0)创建初始值为0的信号量
  2. 调用dispatch_async(dispatch_get_main_queue(), ^{...})向主队列提交待执行的block,主队列是串行队列,提交的block必须等主线程当前正在执行的任务结束后才会被调度
  3. 主线程紧接着执行dispatch_wait(waitSem, DISPATCH_TIME_FOREVER),因为信号量初始值为0,主线程直接进入阻塞休眠状态,等待信号量唤醒
  4. 负责调用dispatch_semaphore_signal唤醒信号量的block还在主队列等待调度,主线程已经被阻塞无法执行该block,最终形成永久死锁。
解决方案

分两种适配场景:

  • 场景1:当前代码必须运行在主线程
    不要使用信号量做等待,把dispatch_wait之后需要执行的逻辑,直接移到提交到主队列的block内部即可,修改后示例:
dispatch_async(dispatch_get_main_queue(), ^{
  // do something else
  // 把原来dispatch_wait之后要执行的逻辑写在这里
});
  • 场景2:当前代码可迁移到后台线程执行
    把整段逻辑放到后台队列执行,此时dispatch_wait阻塞的是后台线程,主线程可以正常调度待执行的block发送信号量,不会死锁,修改后示例:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  dispatch_semaphore_t waitSem = dispatch_semaphore_create(0);
  dispatch_async(dispatch_get_main_queue(), ^{
    // do something else
    dispatch_semaphore_signal(waitSem);
  });
  dispatch_wait(waitSem, DISPATCH_TIME_FOREVER);
  // 原来dispatch_wait之后要执行的逻辑写在这里
});

内容的提问来源于stack exchange,提问作者jackie_G

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 04:15:01