【发布时间】:2018-12-26 16:52:33
【问题描述】:
简而言之:
我有一个可从多个线程访问的计数器变量。虽然我已经实现了多线程读/写保护,但变量似乎仍然 - 以一种不一致的方式 - 同时被写入,导致计数器的结果不正确。
进入杂草:
我使用“for 循环”在后台触发大约 100 个 URL 请求,每个请求都在其“DispatchQueue.global(qos: .userInitiated).async”队列中。
这些进程是异步的,一旦完成,它们就会更新“计数器”变量。这个变量应该是多线程保护的,这意味着它总是从一个线程访问并且是同步访问的。然而,有些事情是错误的,有时两个线程会同时访问变量,导致计数器没有正确更新。这是一个示例,假设我们有 5 个 URL 需要获取:
我们从 5 处的 Counter 变量开始。
1 URL 请求完成 -> 计数器 = 4
2 URL 请求完成 -> 计数器 = 3
3 URL 请求完成 -> 计数器 = 2
4 URL 请求完成(出于某种原因——我假设变量被同时访问)-> 计数器 2
5 URL 请求完成 -> 计数器 = 1
如您所见,这导致计数器为 1,而不是 0,这会影响代码的其他部分。此错误发生不一致。
这是我对计数器变量使用的多线程保护:
- 专用全局队列
//后台队列同步数据访问文件private let globalBackgroundSyncronizeDataQueue = DispatchQueue(标签: "globalBackgroundSyncronizeSharedData")
- 始终通过访问器访问变量:
var numberOfFeedsToFetch_Value: Int = 0 var numberOfFeedsToFetch: Int { set (newValue) { globalBackgroundSyncronizeDataQueue.sync() { self.numberOfFeedsToFetch_Value = newValue } } get { return globalBackgroundSyncronizeDataQueue.sync { numberOfFeedsToFetch_Value } } }
我认为我可能遗漏了一些东西,但我使用了分析并且一切似乎都很好,还检查了文档,我似乎正在做他们推荐的事情。非常感谢您的帮助。
谢谢!!
【问题讨论】:
-
如何使用锁定机制
NSLock。
标签: swift multithreading queue dispatch