gpt4 book ai didi

ios - DispatchQueue 障碍问题

转载 作者:行者123 更新时间:2023-11-28 09:24:34 25 4
gpt4 key购买 nike

试图制作线程安全数组,但它不像我预期的那样工作

import Foundation
import PlaygroundSupport

PlaygroundPage.current.needsIndefiniteExecution = true

public class SafeArray<Element> {
private var array = [Element]()
private let queue = DispatchQueue(label: "queueBarrier", attributes: .concurrent)

public func append(element: Element) {
queue.async(flags: .barrier) {
self.array.append(element)
}
}

public var elements: [Element] {
var result = [Element]()
queue.sync {
result = self.array
}
return result
}

public var last: Element? {
var result: Element?
queue.sync {
result = self.array.last
}
return result
}
}




var safeArray = SafeArray<Int>()
var array = Array<Int>()

DispatchQueue.concurrentPerform(iterations: 10) { (int) in
let last = array.last ?? 0
array.append(last + 1)
print("array = [..\(last)]")
}

print(array)

DispatchQueue.concurrentPerform(iterations: 10) { (int) in
let last = safeArray.last ?? 0
safeArray.append(element: last + 1)
print("safeArray = [..\(last)]")
}

print(safeArray.elements)

output of my code

我预计数组应该有一些困惑但 safeArray 应该有从 0 到 9 的数字。

我知道 array 有 3 个值,但 safeArray 有 10 个值,如预期的那样。但为什么这个值不是从 0 到 9?

谢谢!

最佳答案

barrier 的工作方式是确保 DispatchWorkItem(append(:_) 的 block )等待所有其他DispatchWorkItem 在执行其 perform( block 内的代码)之前完成。因此,障碍

如果仔细观察,您会在最后 调用中找到一个 (DispatchWorkItem)。由于您在 DispatchQueue.concurrentPerform同时做的第一件事是调用 last,因此您将拥有一堆 DispatchWorkItem正在排队等候。

这意味着您所有的 append(_:) 调用都将等待,因为它们被标记为 barrier 并且您的 last 调用将全部首先执行,因此得到很多零,直到 last 的所有 DispatchWorkItem 完成,然后再压缩两个 appends(_:)

barrier 在并发队列中的工作方式是,它实际上会等到所有待处理的 DispatchWorkItem 完成后才开始,并且不会同时开始其他任何事情直到它完成。它暂时“禁用”队列的并发性质,除非我弄错了。

我通常不太愿意按照其他人的建议引入锁或信号量,除非您首先了解 GCD 的工作原理,否则它们可能会导致更多问题。

看起来您正在尝试解决两件事,首先是让 append(_:) 并发工作,然后根据其当前状态在并行操作中改变数组。尝试首先分解您要解决的问题,以便有人可以给您更好的答案。

关于ios - DispatchQueue 障碍问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46579268/

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