2012-08-12 82 views
1

可能重複:
Do I need to protect read access to an STL container in a multithreading environment?線程安全設置

如果某個線程讀取:設置或:地圖時另一個線程寫入該組或地圖,會發生什麼?例外?

現在我用讀寫鎖,但我想刪除鎖定,因爲writining操作並不頻繁,經常閱讀操作。

+1

標準容器不是線程安全的。 – Xeo 2012-08-12 14:21:30

+0

@Xeo,所以會當一個線程讀取容器時,另一個寫它會怎麼樣呢?例外? – RomanKarpuk 2012-08-12 14:23:48

+3

@RomanKarpuk未定義的行爲! – juanchopanza 2012-08-12 14:41:25

回答

4

比賽條件會發生:根據所做的事情CPU的訂貨,你們每個人都及時收到不同的結果。如果一個迭代器失效(例如通過刪除在一個線程和其他線程指向,現在無效的內存迭代的項目)中的其他線程使用,然後,你會得到不確定的行爲,所以要謹慎死嬰,粘土傀儡,並常去的地方,與更多的可能就是內存設計缺陷,延遲內存設計缺陷和運行時崩潰一起。

C++ 11引入mutex和其他線程設施:保護您的讀取和如果你必須寫這些。

+0

「時,map/set操作符可能會改變結構」你會得到一個段錯誤「 - 你可能會遇到段錯誤。如果被無效化的迭代器指向的節點已經被釋放並重新分配給別的東西,你可能會得到一個不太明顯的錯誤。 – 2012-08-12 15:27:24

+0

最糟糕的bug的孩子不是段錯誤,而是似乎在工作流程中起作用並使後者崩潰的錯誤。在發生錯誤時在segfaults中感謝你。 – 2012-08-12 16:13:45

+0

@Loki:我的錯誤行爲比之後在工作流中崩潰的情況更糟糕。例如,不會崩潰,但會導致程序的某些完全不相關的部分產生錯誤的答案。但我完全同意,越早越明顯,越野車程序做錯了,越好越好。因此,出現錯誤的段錯誤是非常好的。 – 2012-08-12 17:55:24

0

標準集裝箱不是線程安全的,他們都沒有指定具有Java中的「快速失敗」迭代器。因此,至少有兩件事情可以去錯未受保護的併發訪問:

  1. 的容器,這是不確定的行爲
  2. 一個線程無效迭代器和後另一個線程上的數據爭用的等值迭代器。這也是不確定的行爲,但它不一定是一個數據的比賽,並會在一個單線程程序中的錯誤了。這只是簡單一點,當他們在不同的線程已經習慣了失去跟蹤多個迭代器相同的容器上。

有人可能會說C++的理念是「快速成功」,而不必介意程序員失敗時會發生什麼;-)。因此,沒有內置的鎖對於許多用戶來說是冗餘的。相反,它是你的問題 - 你寧願不開心的是,鎖放緩這一計劃,比不快樂的,他們正在放慢這個程序,你寫過所有其他程序使用set,即使置不同時訪問的

寫操作並不頻繁,經常閱讀操作。

這正是讀寫器鎖定應該表現良好的情況。你可以改善你的情況的唯一方法是,如果你可以在「不經常」降低寫入操作爲「從不」,想必你不能哪些。如果它們是由一個線程修改