我们如何在Swift中实施等待/通知
在Java中,我们可以执行以下操作:我们如何在Swift中实施等待/通知,swift,multithreading,synchronization,Swift,Multithreading,Synchronization,在Java中,我们可以执行以下操作: synchronized(a) { while(condition == false) { a.wait(time); } //critical section ... //do something } 上面是一个条件同步块,它等待一个条件成功执行一个关键部分 当a.wait被执行时(比如100毫秒),线程在该持续时间内退出临界区&执行由对象a同步的其他临界区,这使条件为真 当条件成功时,下一次当前线程进入临
synchronized(a) {
while(condition == false) {
a.wait(time);
}
//critical section ...
//do something
}
上面是一个条件同步块,它等待一个条件成功执行一个关键部分
当a.wait被执行时(比如100毫秒),线程在该持续时间内退出临界区&执行由对象a同步的其他临界区,这使条件为真
当条件成功时,下一次当前线程进入临界区并计算条件时,循环退出并执行代码
需要注意的要点:
1.同一对象同步的多个关键部分。
2.线程仅在等待期间不在关键部分。等待结束后,线程再次处于临界段
在Swift 4中,使用DispatchSemaphore,下面的方法是否正确
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
}
}
回答我的问题
在下面的伪代码中使用了NSLock的一个实例来锁定和解锁
while true {
//lock
if condition == false {
//unlock
//sleep for sometime to prevent frequent polling
continue
} else {
//execute critical section
//...
//unlock
break
}
}
信号量
您可以使用DispatchSemaphore
解决此问题
让我们看看这段代码。
这里我们有一个信号量
,存储
类型为String?
的属性和一个串行队列
let semaphore = DispatchSemaphore(value: 0)
var storage: String? = nil
let serialQueue = DispatchQueue(label: "Serial queue")
制作人
这里我们有一个函数:
生产者
函数之前运行消费者
consumer()
producer()
结果
Optional("Hello world!")
它是如何工作的?
consumer()
函数的主体在串行队列中异步执行
serialQueue.async {
...
}
这相当于您的synchronized(a)
。实际上,根据定义,一个串行队列一次将运行一个闭包
闭包内的第一行是
semaphore.wait()
因此,闭包的执行被停止,等待信号量发出绿灯
这发生在另一个队列(不是主队列)上,因此我们没有阻塞主线程
现在执行producer()。它在与主队列不同的队列上等待3秒钟,然后填充存储器
,并通过信号量发送信号
最后,consumer()
接收信号并可以运行最后一行
print(storage)
游乐场
如果您想在操场上运行此代码,请记住
import PlaygroundSupport
还要跑这条线
PlaygroundPage.current.needsIndefiniteExecution = true
“while true”实际上是一个可怕的想法。循环将大部分时间花在nslock或睡眠中。while true仅适用于流量控制。它工作得很好。。
func producer() {
DispatchQueue.global().asyncAfter(deadline: .now() + 3) {
storage = "Hello world!"
semaphore.signal()
}
}
print(storage)
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true