閱讀867 返回首頁    go 阿裏雲 go 技術社區[雲棲]


String copy on write 引發的線程不安全



   一個string對象的讀操作是線程安全的麼?答案是否定的。讀取一個string在某些情況下是線程不安全的。這是為什麼呢?原因就是string在優化存儲空間時采用的策略cow。


什麼是cow

     Cow 是copy on write的縮寫。String 為了減少內存拷貝,當兩個string對象的內容相同時,他們指向同一塊內存空間,並通過引用計數來表示有多少對象引用了這塊內存。當其中某個string對象的內容發生改變時,string會先重新分配一塊空間,把原來的內容拷貝到新空間,原來的空間的引用計數減去1。


什麼情況下引發cow

      當程序判斷string對象要改變時,就會引發cow。一種比較少見的情況就是,程序獲得了string對象的非const引用,那麼程序無法判斷在接下來的操作中是否會改變這個string對象。所以會觸發cow操作。一個典型的例子是string::operator[], 當一個非const對象調用[]操作符時,實際上獲得的是對象的非const引用,於是引發了cow。


危害
      上邊的operator[],如果隻是為了讀取字符串的話,那麼我們期望這個操作應該是線程安全的。但實際上這個讀操作包含了寫操作,假如另一個線程同時在讀這個字符串的話,程序就有可能在這裏使內存寫壞。為了解決這個問題,必須給string對象限定為const.


我在產品中發現了這個問題,為了調查這個問題花費了3周的時間,並在第四周時從理論上解釋通了這個原因。

最後更新:2017-04-03 16:59:46

  上一篇:go HIGHCHARTS後台取數+SSH
  下一篇:go HDU 4341 判斷共線+背包