Semaphore object deallocated while in use

1,689 阅读1分钟

今天遇到一个坑:

BUG IN CLIENT OF LIBDISPATCH: Semaphore object deallocated while in use

原来创建 semaphore 的代码:

DispatchSemaphore(value: 1)

找了下网上的答案:

Somewhat more succinct answer: You are creating the semaphore with the wrong value, it should be zero. Creating it with a value of 1 means you are later releasing a semaphore that's still "in use" and GCD is deliberately generating an illegal instruction in order to help you debug the fact that you have a semaphore with more waiters on it.

就是在 deinit 的时候,semaphore 的 dValue 小于 rawValue,被系统认为“in use”,从而导致了 crash。

逻辑是这样的:

if (dsema->dsema_value < dsema->dsema_orig) {
    DISPATCH_CLIENT_CRASH("Semaphore/group object deallocated while in use");
}

所以,最终的解决方法是:

  1. 创建 semaphore 时传入初始值 0,然后再通过 signal() 手动 +1
  2. 在 deinit 的时候再 signal() 一次,确保 dsema->dsema_value < dsema->dsema_orig 不成立

参考链接:

Why does this code cause “EXC_BAD_INSTRUCTION”?

dispatch_semaphore