Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ssl/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我们如何在Swift中实施等待/通知_Swift_Multithreading_Synchronization - Fatal编程技术网

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

我们如何在Swift中实施等待/通知,swift,multithreading,synchronization,Swift,Multithreading,Synchronization,在Java中,我们可以执行以下操作: synchronized(a) { while(condition == false) { a.wait(time); } //critical section ... //do something } 上面是一个条件同步块,它等待一个条件成功执行一个关键部分 当a.wait被执行时(比如100毫秒),线程在该持续时间内退出临界区&执行由对象a同步的其他临界区,这使条件为真 当条件成功时,下一次当前线程进入临

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

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")
制作人 这里我们有一个函数:

  • 等待3秒钟
  • 将“Hello world”写入存储器
  • 通过信号量发送信号
  • 消费者 这里我们有一个函数

  • 等待信号灯发出的信号
  • 打印存储的内容
  • 试验 现在,我将在
    生产者
    函数之前运行
    消费者

    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