簡體   English   中英

使用c ++ 11的std :: thread,何時修改全局變量是線程安全的?

[英]Using c++11's std::thread, when is modifying global variables thread-safe?

考慮以下來源:

#include <string>
#include <iostream>
#include <thread>

using namespace std;

int *up;

void testf(){
    for(int i = 0; i < 1000; i++)
        for(int f = 0; f < 11; f++)
            up[i]++;
}

int main() {
    up = new int[1000];

    std::thread tt[7];

    for(int ts=0;ts<7;ts++) {
        tt[ts]=std::thread(testf);
    }

    for(int ts=0;ts<7;ts++) {
        tt[ts].join();
    }

    for(int i = 0; i < 1000; i++)
        cout << up[i];
    cout << endl;
    delete[] up;
    return 0;
}

我故意寫沒有任何互斥量的同一個int數組。 testf()的for循環會將int up[1000]的所有成員增加11,並且我們有7個線程。 所以輸出應該是77777777 ...(2000 Sevens)

但是有時候,當我運行exe時,會得到如下數字:

...7777777066676672756866667777777777777377777366667777777...

為什么會這樣?

(要在linux上編譯:g ++ -std = c ++ 11 -pthread)

原因是“ up [i] ++;” 不是線程安全操作。 它基本上是這樣做的:

  1. 讀取up [i]的值
  2. 將一個加到讀取值
  3. 寫入值up [i]

有兩個線程會發生什么:

  • 線程1 1)讀取up [i]的值(3)
  • 線程1 2)將一個加到讀取值(4)
  • 線程1 3)寫入up [i]的值(4)

  • 線程2 1)讀取up [i]的值(4)

  • Thread2 2)將讀取的值加1(5)
  • Thread2 3)寫值up [i](5)

可能會發生什么:

  • 線程1 1)讀取up [i]的值(3)
  • 線程2 1)讀取up [i]的值(3)

  • 線程1 2)將一個加到讀取值(4)

  • 線程1 3)寫入up [i]的值(4)
  • 線程2 2)將一加到讀取值(4)
  • Thread2 3)寫值up [i](4)

因此,兩個線程都將4寫入數組!

要解決此問題,您需要對數組進行互斥或原子遞增操作: http : //baptiste-wicht.com/posts/2012/07/c11-concurrency-tutorial-part-4-atomic-type.html

暫無
暫無

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

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