【问题标题】:Mutex alternatives in swift快速的互斥体替代品
【发布时间】:2018-02-20 12:15:55
【问题描述】:

我在多个线程之间有一个共享内存。我想阻止这些线程同时访问这块内存。 (如生产者-消费者问题)

问题

一个线程将元素添加到队列中,另一个线程读取这些元素并删除它们。他们不应该同时访问队列。

解决此问题的一种方法是使用 Mutex。

我发现,Swift 中没有 Mutex。 Swift 中是否有替代方案?

【问题讨论】:

  • 我想你可以找 Grand Central Dispatch 看看这个:raywenderlich.com/148513/…
  • 使用Dispatch Queue可以解决这类问题。
  • @rmaddy 我编辑了我的问题。是的,我想这样做。
  • 请参阅stackoverflow.com/questions/45710200/… 了解一些想法。
  • 您可以使用调度信号量。用 1 初始化,并在访问信号量之前/之后等待/发出信号。

标签: ios swift swift3 concurrency mutual-exclusion


【解决方案1】:

对此有很多解决方案,但我使用串行队列来执行此类操作:

let serialQueue = DispatchQueue(label: "queuename")
serialQueue.sync { 
    //call some code here, I pass here a closure from a method
}

编辑/更新:也适用于信号量:

let higherPriority = DispatchQueue.global(qos: .userInitiated)
let lowerPriority = DispatchQueue.global(qos: .utility)

let semaphore = DispatchSemaphore(value: 1)

func letUsPrint(queue: DispatchQueue, symbol: String) {
    queue.async {
        debugPrint("\(symbol) -- waiting")
        semaphore.wait()  // requesting the resource

        for i in 0...10 {
            print(symbol, i)
        }

        debugPrint("\(symbol) -- signal")
        semaphore.signal() // releasing the resource
    }
}

letUsPrint(queue: lowerPriority, symbol: "Low Priority Queue Work")
letUsPrint(queue: higherPriority, symbol: "High Priority Queue Work")

RunLoop.main.run()

【讨论】:

  • 让我知道我的方法是否解决了您的问题或者为我提供了其他方法,我也想有一些有效的方法来解决这个问题
【解决方案2】:

感谢beshio的评论,你可以这样使用信号量:

let semaphore = DispatchSemaphore(value: 1)

在使用资源之前使用等待:

semaphore.wait()
// use the resource

使用释放后:

semaphore.signal()

在每个线程中执行此操作。

【讨论】:

    【解决方案3】:

    正如人们(包括我)评论的那样,有几种方法可以实现这种锁定。但我认为调度信号量比其他信号量更好,因为它的开销似乎最小。正如在 Apples doc, "Replacing Semaphore Code" 中发现的那样,除非信号量已被锁定(= 零),否则它不会进入内核空间,这是代码进入内核以切换线程的唯一情况。我认为信号量在大多数情况下都不为零(不过,这当然是特定于应用程序的问题)。因此,我们可以避免大量开销。

    关于 dispatch semaphore 的更多评论,这是与上面相反的情况。如果你的线程有不同的执行优先级,并且更高优先级的线程不得不长时间锁定信号量,那么分派信号量可能不是解决方案。这是因为等待线程之间没有“队列”。在这种情况下发生的是更高的优先级 线程大部分时间获取并锁定信号量,而较低优先级的线程只能偶尔锁定信号量,因此,大多只是等待。如果这种行为对您的应用程序不利,则必须考虑使用调度队列。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-12-18
      • 2020-09-06
      • 1970-01-01
      • 1970-01-01
      • 2017-12-22
      • 1970-01-01
      • 2013-08-12
      相关资源
      最近更新 更多