gpt4 book ai didi

swift - 我们如何在 Swift 中实现等待/通知

转载 作者:搜寻专家 更新时间:2023-11-01 05:32:53 25 4
gpt4 key购买 nike

在 Java 中,我们可以这样做:

synchronized(a) {
while(condition == false) {
a.wait(time);
}
//critical section ...
//do something
}

上面是一个条件同步块(synchronized block),它等待条件变为成功以执行临界区。

当执行 a.wait 时(例如 100 毫秒),线程会在该持续时间内退出临界区,并且由对象 a 执行同步的其他一些临界区,从而使条件为真。

当条件成功时,下一次当前线程进入临界区并评估条件,循环退出并执行代码。

注意事项:1. 多个临界区由同一个对象同步。2. 线程仅在等待期间不处于临界区。一旦 wait 出来,线程再次进入临界区。

以下是使用 DispatchSemaphore 在 Swift 4 中执行相同操作的正确方法吗?

while condition == false {
semaphore1.wait(duration)
}
semaphore1.wait()
//execute critical section
semaphore1.signal()

当我们进入临界区时,条件可能会被修改。

因此,我们可能必须执行如下操作才能实现 Java 行为。在 Swift 中有更简单的方法吗?

while true {
//lock
if condition == false {
//unlock
//sleep for sometime to prevent frequent polling
continue
} else {
//execute critical section
//...
//unlock
break
}
}

最佳答案

信号量

您可以使用 DispatchSemaphore 解决这个问题。

让我们看一下这段代码。这里我们有一个 semaphorestorage 类型的 String? 属性和一个串行队列

let semaphore = DispatchSemaphore(value: 0)
var storage: String? = nil
let serialQueue = DispatchQueue(label: "Serial queue")

制作人

func producer() {
DispatchQueue.global().asyncAfter(deadline: .now() + 3) {
storage = "Hello world!"
semaphore.signal()
}
}

这里我们有一个函数:

  1. 等待 3 秒
  2. 将“Hello world”写入存储
  3. 通过信号量发送信号

消费者

func consumer() {
serialQueue.async {
semaphore.wait()
print(storage)
}
}

这里有一个函数

  1. 等待信号量的信号
  2. 打印存储内容

测试

现在我要运行 consumer BEFORE producer 函数

consumer()
producer()

结果

Optional("Hello world!")

它是如何工作的?

func consumer() {
serialQueue.async {
semaphore.wait()
print(storage)
}
}

consumer() 函数的主体在串行队列中异步执行。

serialQueue.async {
...
}

This is the equivalent of your synchronized(a). Infact, by definition, a serial queue will run one closure at the time.

闭包内的第一行是

semaphore.wait()

因此闭包的执行被停止,等待信号量的绿灯。

This is happening on a different queue (not the main one) so we are not blocking the main thread.

func producer() {
DispatchQueue.global().asyncAfter(deadline: .now() + 3) {
storage = "Hello world!"
semaphore.signal()
}
}

现在 producer() 被执行了。它在与主队列不同的队列上等待 3 秒,然后填充存储并通过信号量发送信号。

最后 consumer() 收到信号,可以运行最后一行

print(storage)

Playground

如果你想在 Playground 中运行这段代码,记得要

import PlaygroundSupport

并运行这条线

PlaygroundPage.current.needsIndefiniteExecution = true

关于swift - 我们如何在 Swift 中实现等待/通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51798378/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com