2014-10-28 127 views
4
void foo() { 
    static int id = 0; 
    const int local_id = id++; 
    //do something with local_id; 
} 

多線程可以多次並行調用foo。我希望foo的每次調用都使用local_id的「唯一」值。上面的代碼可以嗎?我想知道在第一個線程增加值之前,第二個線程是否將id的值分配給local_id。如果它不安全,是否有任何標準解決方案?靜態局部變量的線程安全增量

+9

使用['std :: atomic_int'](http://en.cppreference.com/w/cpp/header/atomic) – Mgetz 2014-10-28 14:27:51

+0

請注意,id的*初始化*可能或可能不是線程安全,這取決於您的編譯器支持「魔術靜態」。 – dlf 2014-10-28 14:30:33

+0

@dlf對,但值得一提的是,C++ 11需要「魔術靜態」,所以這是編譯器一致性問題,而不是支持可選功能。 – Angew 2014-10-28 14:38:09

回答

5

您的代碼不是線程安全的,因爲多個線程可以同時讀取id並生成相同的值local_id

如果你想有一個線程安全的版本,使用std::atomic_int,這是可以在C++ 11:

void foo() { 
    static std::atomic_int id; 
    const int local_id = id++; 
    //do something with local_id; 
} 
+3

請注意,如果您使用的是Microsoft編譯器,那麼'id'的初始化將不會是線程安全的,因爲它們尚不支持「魔術靜態」(截至VS2013)。換句話說,如果'foo'從來沒有被調用過,然後兩個線程同時調用它,'id'的構造函數可以運行兩次,併發不可預知的結果。 – dlf 2014-10-28 14:55:59

0

您的代碼不是線程安全的,因爲兩個線程可以在同一時間遞增ID。

使用mutual exclusion或std :: atomic作爲共享ID變量。

+1

如何在上述情況下使用互斥?你能否詳細說明一下? – Wolf 2014-10-28 14:33:05

+0

將靜態包裝在類中,並提供在執行操作之前獲取互斥鎖的get/increment方法。 – Claudio 2014-10-28 14:50:50