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

时间:2018-08-11 09:38:09

标签: swift multithreading synchronization

在Java中,我们可以执行以下操作:

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

上面是一个条件同步块,它等待条件成功执行关键部分。

当执行a.wait(例如100毫秒)时,线程会在该持续时间内退出关键部分,并执行由对象a同步的其他一些关键部分,这使条件成立。

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

要注意的重要事项: 1.多个关键部分由同一对象同步。 2.仅在等待期间,线程不在关键区域中。等待一经出现,线程再次处于关键区域。

以下是使用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
    }
}

2 个答案:

答案 0 :(得分:-1)

回答我的问题。

使用NSLock实例在下面的伪代码中进行锁定和解锁。

std::vector<std::vector<double>> data

答案 1 :(得分:-1)

信号量

您可以使用DispatchSemaphore解决此问题。

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

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函数

之前
producer

结果

consumer()
producer()

它如何工作?

Optional("Hello world!")

func consumer() { serialQueue.async { semaphore.wait() print(storage) } } 函数的主体被异步执行到串行队列中。

consumer()
  

这等效于您的serialQueue.async { ... } 。实际上,根据定义,串行队列将同时运行一次关闭。

闭包内的第一行是

synchronized(a)

因此,停止执行关闭,等待信号灯发出绿灯。

  

这是在另一个队列(不是主队列)上发生的,因此我们没有阻塞主线程。

semaphore.wait()

现在执行producer()。它在与主队列不同的队列上等待3秒,然后填充func producer() { DispatchQueue.global().asyncAfter(deadline: .now() + 3) { storage = "Hello world!" semaphore.signal() } } 并通过信号量发送信号。

最后storage接收信号并可以运行最后一行

consumer()

游乐场

如果您想在Playground中运行此代码,请记住

print(storage)

并运行此行

import PlaygroundSupport