gpt4 book ai didi

swift - 变量多线程访问 - 损坏

转载 作者:行者123 更新时间:2023-11-30 11:19:49 27 4
gpt4 key购买 nike

简而言之:

我有一个可以从多个线程访问的计数器变量。尽管我已经实现了多线程读/写保护,但该变量似乎仍然以不一致的方式同时写入,导致计数器结果不正确。

深入杂草:

我使用的“for 循环”会在后台触发大约 100 个 URL 请求,每个请求都位于其“DispatchQueue.global(qos: .userInitiated).async”队列中。

这些进程是异步的,一旦完成,它们就会更新“计数器”变量。该变量应该是多线程保护的,这意味着它总是从一个线程访问并且是同步访问的。但是,有些问题,有时两个线程会同时访问该变量,导致计数器无法正确更新。这是一个例子,假设我们有 5 个 URL 需要获取:

我们从 Counter 变量 5 开始。

1 个 URL 请求完成 -> 计数器 = 4

2 个 URL 请求完成 -> 计数器 = 3

3 个 URL 请求完成 -> 计数器 = 2

4 URL 请求完成(出于某种原因 - 我假设同时访问变量)-> 计数器 2

5 个 URL 请求完成 -> 计数器 = 1

正如您所看到的,这会导致计数器变为 1,而不是 0,从而影响代码的其他部分。此错误的发生不一致。

这是我对计数器变量使用的多线程保护:

  1. 专用全局队列

//Background queue to syncronize data access fileprivate let globalBackgroundSyncronizeDataQueue = DispatchQueue(label: "globalBackgroundSyncronizeSharedData")

  • 变量始终通过访问器访问:
  • var numberOfFeedsToFetch_Value: Int = 0
    var numberOfFeedsToFetch: Int {
    set (newValue) {
    globalBackgroundSyncronizeDataQueue.sync() {
    self.numberOfFeedsToFetch_Value = newValue
    }
    }
    get {
    return globalBackgroundSyncronizeDataQueue.sync {
    numberOfFeedsToFetch_Value
    }
    }
    }

    我认为我可能遗漏了一些东西,但我已经使用了分析,一切似乎都很好,还检查了文档,我似乎正在按照他们的建议进行操作。非常感谢您的帮助。

    谢谢!!

    最佳答案

    苹果论坛的回答:https://forums.developer.apple.com/message/322332#322332 :

    The individual accessors are thread safe, but an increment operation isn't atomic given how you've written the code. That is, while one thread is getting or setting the value, no other threads can also be getting or setting the value. However, there's nothing preventing thread A from reading the current value (say, 2), thread B reading the same current value (2), each thread adding one to this value in their private temporary, and then each thread writing their incremented value (3 for both threads) to the property. So, two threads incremented but the property did not go from 2 to 4; it only went from 2 to 3. You need to do the whole increment operation (get, increment the private value, set) in an atomic way such that no other thread can read or write the property while it's in progress.

    关于swift - 变量多线程访问 - 损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51407597/

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