C++11多線程類庫中提供了 include包含了很多原子類型 原子操作 若幹彙編指令具有讀-修改-寫類型,也就是說它們訪問存儲器單元兩次,第一次讀原值,第二次寫新值 假定運行在兩個cpu上的兩個內核控制路徑試圖通過執行非原子操作來同時讀-修改-寫同一個存儲器。 首先兩個cpu都試圖讀同一單元,然後 ...
C++11多線程類庫中提供了
include
原子操作
若幹彙編指令具有讀-修改-寫類型,也就是說它們訪問存儲器單元兩次,第一次讀原值,第二次寫新值
假定運行在兩個cpu上的兩個內核控制路徑試圖通過執行非原子操作來同時讀-修改-寫同一個存儲器。
首先兩個cpu都試圖讀同一單元,然後使用不同的方式修改讀取的內容之後將其寫入該存儲單元。
雖然最終兩個寫操作都會成功,但是全局結果是不對的,因為兩個CPU寫入同一記憶體單元,因此兩個交錯的讀-修改-寫操作成了一個單獨的操作
避免由於"讀-修改-寫"指令引起的競爭條件的最容易的辦法就是確保這樣的操作在晶元級是原子的,任何一個這樣的操作度必須以單個指令執行,中間不能中斷,且避免其他的CPU訪問同一存儲器單元,這樣很小的原子操作可以建立在其它更靈活機制的基礎上以創建臨界區。
視窗賣票案例中的 ticketCount++ ;ticketCount--不是線程安全的
我們原來是通過lock_guard(互斥鎖) 來保證的
互斥鎖是比較重的,對臨界區代碼做得事情稍微複雜,多. OK
對一些簡單的情況,我們使用CAS來保證上面的 ++ --操作的原子特性就足夠了,無鎖操作.
C++11中的 automic頭文件中包含了很多原子操作
volatile std::automic_bool isReadu=false;//volatile 不讀緩衝中的值
volatile std::automic_int mycount=0;
void task(){
while(!isReady){
std::this_thread::yied();//線程出讓當前的cpu時間片,等待下一次調度
}
for(int i=0;i<100;i++){
mycount++;
}
}
int main(){
list<std::thread> tlist;
for(int i=0;i<3;i++){
tlist.push_back(std::thread(task));
}
std::this_thread::sleep_for(std::chrono::sedonds(3));
isReady=true;
for(std::thread &t : tlist){
t.join();
}
}