【问题标题】:Can I use a DispatchSemaphore to control a thread on main queue?我可以使用 DispatchSemaphore 来控制主队列上的线程吗?
【发布时间】:2019-08-28 13:14:09
【问题描述】:

显然,如果我处理不同的队列,我只能使用 DispatchSemaphore。但是如果我想在同一个队列(在本例中是主队列)上运行异步代码怎么办。

let s = DispatchSemaphore(value : 0)
DispatchQueue.main.async {
   s.signal()
}
s.wait()

这个sn-p不起作用,因为异步代码也在等待,因为信号量阻塞了主队列。 我可以用信号量做到这一点吗?还是我需要在不同的队列上运行异步代码?

ps。我知道我可以在这个 sn-p 中使用同步,而不是异步和信号量。但这只是重现异步调用的示例代码。

【问题讨论】:

  • DispatchSemaphore 的全部意义在于控制跨多个线程对资源的访问。在单线程中使用它是没有意义的。
  • @ian 如果我调用 async,我不会在不同的线程上运行该代码吗?

标签: swift dispatchsemaphore


【解决方案1】:

所有这些都在主线程中,因此永远不会调用semaphore.signal(),因为线程将在semaphore.wait() 上停止并且不会继续。

如果您尝试运行一些异步代码并让主线程等待它,请在不同的队列上运行该代码,并在完成时发出信号量信号,让主线程继续。

【讨论】:

  • 但是,当我调用异步时(即使它是同一个队列,在这种情况下是主队列),我不是在不同的线程上运行代码吗?如果我在主线程上调用等待,为什么异步代码被阻塞?
  • 在主队列上调用异步仍然会在主线程上,只是不会立即执行
  • 我明白了,所以我想没有时间在异步中运行线程代码,即使在等待之前调用了异步......?
  • 是的,在调用等待之前队列还没有到达异步代码块
【解决方案2】:

如果我想在同一个队列(在本例中是主队列)上运行异步代码怎么办。

然后改用DispatchGroup。这不是DispatchSemaphore 的用途。

在操场上运行此代码。

import Foundation

let d = DispatchGroup()
var v:Int = 1
d.enter()
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
    v = 7
    d.leave()
}

d.notify(queue: DispatchQueue.main) {
    print("v = \(v)")
}

输出将是v = 7。如果您注释掉d.enter()d.leave(),那么输出将为v = 1

如果我调用 async,我不会在不同的线程上运行该代码吗?

不,您需要了解一般的线程运行循环和iOS's Main Event Loop specifically

【讨论】:

  • 谢谢。没有冒犯,但我认为你需要理解问题并阅读答案。 1)问题已经正确回答并在不久前解决。 2)我知道有 DispatchGroup,但我的问题是关于 DispatchSemaphore 以更好地理解这个对象。 3)您的 sn-p 工作的原因是您可以将 notify() 与 dispatchGroup 一起使用。如果你调用 dispatchGroup.wait() 你会遇到同样的问题。
  • 4) 关于“如果我调用异步,我不是在不同的线程上运行该代码吗?”的问题,这已经回答了,所以不需要写“你需要了解...”欢呼声
  • @aneuryzm 这个问题和答案不仅是给你的,也是给其他人的。要“在同一个队列上运行异步代码”,应该使用 DispatchGroup 而不是 DispatchSemaphore。这个问题是一个 X,Y 问题。停止主线程通常是一个错误。
  • @aneuryzm 关于“需要理解”,您的所有问题都表明对运行循环和线程的基本无知。我提供了运行循环的文档链接以提供帮助,因为这些文档很难找到。而你上面对dispatchGroup.wait的评论表明你还是不明白。
  • 你的回答和最后这些cmets绝对表明了一种自负的态度。该问题已在问题 cmets 和原始接受的答案中得到回答。您提供的其他(不是严格要求的)信息(DispatchGroup)不完整:那么作为可能的解决方案的 DispatchWorkItem 呢? “文档很难找到”的链接实际上很容易找到:只需谷歌“Apple 线程”,您就会在第二个位置看到结果。最后,我欢迎您对我对该主题的“根本无知”发表意见,这对于获得一些反馈总是有用的。
猜你喜欢
  • 2013-01-03
  • 2010-09-20
  • 2011-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-02
  • 1970-01-01
  • 2017-08-30
  • 2023-03-21
相关资源
最近更新 更多