簡體   English   中英

可變多線程訪問-損壞

[英]Variable Multithread Access - Corruption

簡而言之:

我有一個計數器變量,可以從許多線程訪問。 盡管我已經實現了多線程讀/寫保護,但該變量似乎仍然(以一種不一致的方式)被同時寫入,從而導致計數器的結果不正確。

進入雜草:

我使用的是“ 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,這會影響代碼的其他部分。 此錯誤不一致地發生。

這是我用於計數器變量的多線程保護:

  1. 專用全局隊列

//同步數據訪問文件的背景隊列專用讓globalBackgroundSyncronizeDataQueue = DispatchQueue(label:“ globalBackgroundSyncronizeSharedData”)

  1. 始終通過訪問器訪問變量:
 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

各個訪問器是線程安全的,但是鑒於您如何編寫代碼,增量操作並不是原子的。 也就是說,當一個線程正在獲取或設置該值時,其他任何線程也都無法獲取或設置該值。 但是,並沒有阻止線程A讀取當前值(例如2),阻止線程B讀取相同的當前值(2),阻止每個線程在其私有臨時變量中向該值添加一個,然后阻止每個線程寫入其遞增值(兩個線程都為3)。 因此,增加了兩個線程,但該屬性沒有從2變為4。 它僅從2變為3。您需要以原子方式執行整個增量操作(獲取,遞增私有值,設置),以使其他任何線程都無法在進行該屬性時讀取或寫入該屬性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM