class SomeViewController: UIViewController {
    let semaphore = DispatchSemaphore(value: 1)
    deinit {
        semaphore.signal() // just in case?
    }
    func someLongAsyncTask() {
        semaphore.wait()
        ...
        semaphore.signal() // called much later
    }
}
如果我告诉信号量等待,然后在信号量被告知发出信号之前取消初始化拥有它的视图控制器,则应用程序会因错误而崩溃Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)。但是,如果我只是调用视图控制器的方法,就可以避免灾难semaphore.signal()。deinit但是,如果异步函数在deinit调用之前返回并且视图控制器被取消初始化,则signal()调用两次,这似乎没有问题。但这样做安全和/或明智吗?
显然,如果我处理不同的队列,我只能使用 DispatchSemaphore。但是如果我想在同一个队列(在这种情况下是主队列)上运行异步代码怎么办。
let s = DispatchSemaphore(value : 0)
DispatchQueue.main.async {
   s.signal()
}
s.wait()
这个片段不起作用,因为异步代码也在等待,因为信号量阻塞了主队列。我可以用信号量做到这一点吗?还是我需要在不同的队列上运行异步代码?
附:我知道我可以在这个片段中使用同步,而不是异步和信号量。但这只是重现异步调用的示例代码。
我正在使用 GCD 来了解信号量的正确实现细节,当 ( https://khanlou.com/2016/04/the-GCD-handbook/ ) 中的一个语句让我困惑时:“调用 .wait() 将阻塞线程,直到.signal() 被调用。这意味着 .signal() 必须从不同的线程调用,因为当前线程完全被阻塞。此外,你永远不应该从主线程调用 .wait(),而只能从后台线程调用。 ” 大多数信号量示例通常从同一队列调用等待和信号,这似乎也工作得很好。我在这里错过了什么吗?
// Pseudocode from: https://khanlou.com/2016/04/the-GCD-handbook/
// on a background queue
let semaphore = DispatchSemaphore(value: 0)
doSomeExpensiveWorkAsynchronously(completionBlock: {
    semaphore.signal()
})
semaphore.wait()
//the expensive asynchronous work is now done
multithreading grand-central-dispatch ios swift dispatchsemaphore
我在 iOS 上使用信号量时遇到问题。我正在实现一项功能来按顺序一个接一个地执行一系列异步方法。
let semaphore = DispatchSemaphore(value: 1)
semaphore.wait()
performFirstTask {
   semaphore.signal
}
semaphore.wait()
performSecondTask {
   semaphore.signal
}
semaphore.wait()
performThirdTask {
   semaphore.signal
}
因此,这按预期工作,但如果用户在等待状态下离开屏幕,就会出现问题,因此当特定任务的回调触发时,视图可能已释放,这会导致崩溃,任何人都可以帮忙吗我来解决这个问题,我没有看到任何释放信号量的方法。
提前致谢
假设我们有一个共享资源,许多不同的全局队列都可以访问该资源,并且为了解决这个问题,我们使用调度信号量来管理该访问。当这些全局队列之一告诉信号量等待时,信号量计数就会递减,并且该线程可以访问共享资源。是否有可能在信号量等待时,另一个(不同的)全局队列尝试访问这个共享资源,而GCD从其池中抓取的线程与为前一个队列(当前正在制作的队列)抓取的线程相同信号量等待)这会导致该线程死锁并阻止信号量计数重新递增?