count++;
count--;
我們知道,++/--操作并不是原子性的,其實對應三條匯編指令來完成的。
- 讀取:從內存中把變量的值讀取到寄存器
- 修改:在寄存器里將變量的值+1/-1
- 寫入:把修改后的值寫入到內存
在單線程環境下,這三個步驟是順序執行的不會有問題。但是在多線程環境下,多個線程可能對同一個變量同時進行++/--操作,從而導致數據競爭的問題。
可以看下面的過程演示。
一:
二:
三:
C++11是通過加鎖來保證++/--操作的原子性的。
std::lock_guard<std::mutext>(mtx);
count++;
std::unlock_guard<std::mutex>(mtx);
互斥鎖是比較重的,臨界區代碼稍稍復雜的情況下建議使用。從系統理論上來講,使用CAS無鎖操作來保證++/--操作的原子性就足夠了,其實并不是不加鎖,只是不在軟件層面上加鎖解鎖,而是在硬件層面上實現的。
#include<iostream>
#include<thread>
#include<list>
#include<atomic>
using namespace std;volatile std::atomic_bool isReady = false;
volatile std::atomic_int myCount = 0;void task()
{while (!isReady){std::this_thread::yield(); // 線程讓出當前的CPU時間片,等待下一次調度}for (int i = 0; i < 100; i++){myCount++;}
}
int main()
{list<std::thread> tlist;for (int i = 0; i < 10; i++){tlist.push_back(std::thread(task));}std::this_thread::sleep_for(std::chrono::seconds(3));isReady = true;for (auto& t : tlist){t.join();}std::cout << "myCount: " << myCount << std::endl;return 0;
}