大佬教程收集整理的这篇文章主要介绍了swift – 一次调用DispatchSemaphore的wait()这几次是否安全?,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
self.semaphore.wait() // +1 self.semaphore.wait() // +1
以下是整个测试代码:
class GCDLockTest { let semaphore = DispatchSemaphore(value: 0) func test() { let queueA = DispatchQueue(label: "Q1") let queueB = DispatchQueue(label: "Q2") let queueC = DispatchQueue(label: "Q3") queueA.async { self.semaphore.wait() // +1 self.semaphore.wait() // +1 print("QueueA gonna sleep") sleep(3) print("QueueA woke up") } queueB.async { self.semaphore.signal() // -1 print("QueueB gonna sleep") sleep(3) print("QueueB woke up") } queueC.async { self.semaphore.signal() // -1 print("QueueC gonna sleep") sleep(3) print("QueueC wake up") } } }
信号量动作保证是线程安全的,如果没有它就没有意义,所以你正在做的事情会很好.你确实可以调用等待两次来概念性地@L_489_11@资源两次.
但是,您有一个阻塞的后台线程.这是一件坏事,因为用于执行调度队列上的块的线程在需要时不会创建,它们是根据基于各种事物(如处理器内核数量)调整大小的池分配的.队列A上的块将占用一个线程,直到队列B和队列C线程都发信号通知信号量.
当您输入函数test()且线程池中只剩下一个线程时,会出现最坏的情况.如果队列A上的块在其他两个块中的任何一个块之前抓取它,则会有一个死锁,因为A将等待信号量,B和C将等待A完成,以便它们可以有一个线程.
最好不要启动A,直到其他两个线程准备好开始它.这可以通过在正确的时间在主线程上执行块来完成.像这样的东西:
class GCDLockTest { var cFinished = false var bFinished = false func test() { let queueA = DispatchQueue(label: "Q1") let queueB = DispatchQueue(label: "Q2") let queueC = DispatchQueue(label: "Q3") queueB.async { DispatchQueue.main.async { bFinished = true if cFinished { queueA.async { print("QueueA gonna sleep") sleep(3) print("QueueA woke up") } } } print("QueueB gonna sleep") sleep(3) print("QueueB woke up") } queueC.async { DispatchQueue.main.async { cFinished = true if bFinished { queueA.async { print("QueueA gonna sleep") sleep(3) print("QueueA woke up") } } } print("QueueC gonna sleep") sleep(3) print("QueueC wake up") } } }
在上面,您不需要任何信号量或其他同步,因为隐含的是所有同步工作都是在串行的主队列上完成的.即,启动A的两个块永远不能同时运行.
这是一种方法,但Apple提供dispatch groups确切的问题.使用调度组,您可以将B和C添加到组中,并让它们在准备好启动A时告诉组.
class GCDLockTest { func test() { let group = DispatchGroup() let queueA = DispatchQueue(label: "Q1") let queueB = DispatchQueue(label: "Q2") let queueC = DispatchQueue(label: "Q3") group.enter() queueB.async { group.leave() print("QueueB gonna sleep") sleep(3) print("QueueB woke up") } group.enter() queueC.async { group.leave() print("QueueC gonna sleep") sleep(3) print("QueueC wake up") } group.notify(queue: queueA) { print("QueueA gonna sleep") sleep(3) print("QueueA woke up") } }
在开始B和C中的每一个之前,输入组.然后在启动B和C之后,我们在组中放置一个通知块,这样当它们都离开组时,A的块在右侧队列中启动.
另见https://developer.apple.com/documentation/dispatch/dispatchgroup
以上是大佬教程为你收集整理的swift – 一次调用DispatchSemaphore的wait()这几次是否安全?全部内容,希望文章能够帮你解决swift – 一次调用DispatchSemaphore的wait()这几次是否安全?所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。