void foo() {
static int id = 0;
const int local_id = id++;
//do something with local_id;
}
多線程可以多次並行調用foo。我希望foo的每次調用都使用local_id的「唯一」值。上面的代碼可以嗎?我想知道在第一個線程增加值之前,第二個線程是否將id的值分配給local_id。如果它不安全,是否有任何標準解決方案?靜態局部變量的線程安全增量
void foo() {
static int id = 0;
const int local_id = id++;
//do something with local_id;
}
多線程可以多次並行調用foo。我希望foo的每次調用都使用local_id的「唯一」值。上面的代碼可以嗎?我想知道在第一個線程增加值之前,第二個線程是否將id的值分配給local_id。如果它不安全,是否有任何標準解決方案?靜態局部變量的線程安全增量
您的代碼不是線程安全的,因爲多個線程可以同時讀取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;
}
請注意,如果您使用的是Microsoft編譯器,那麼'id'的初始化將不會是線程安全的,因爲它們尚不支持「魔術靜態」(截至VS2013)。換句話說,如果'foo'從來沒有被調用過,然後兩個線程同時調用它,'id'的構造函數可以運行兩次,併發不可預知的結果。 – dlf 2014-10-28 14:55:59
您的代碼不是線程安全的,因爲兩個線程可以在同一時間遞增ID。
使用mutual exclusion或std :: atomic作爲共享ID變量。
使用['std :: atomic_int'](http://en.cppreference.com/w/cpp/header/atomic) – Mgetz 2014-10-28 14:27:51
請注意,id的*初始化*可能或可能不是線程安全,這取決於您的編譯器支持「魔術靜態」。 – dlf 2014-10-28 14:30:33
@dlf對,但值得一提的是,C++ 11需要「魔術靜態」,所以這是編譯器一致性問題,而不是支持可選功能。 – Angew 2014-10-28 14:38:09