atomic原子操作:是在新標准C++11,引入了原子操作的概念,並通過這個新的頭文件提供了多種原子操作數據類型,例如,atomic_bool,atomic_int等等
測試程序
#include <iostream> #include <thread> #include <mutex> #include <atomic> #include <time.h> #define TEST_DATA_LENGTH 100000 //每個線程操作次數 #define THREAD_NUM 10 //線程個數 using namespace std;//引入std命名空間 mutex m;//聲明互斥鎖m long n_total = 0; long m_total = 0; atomic<long> a_total = 0;//原子量的初始化 //在不采用互斥鎖和原子類的情況下 void test_f_normal() { for(int i = 0; i < TEST_DATA_LENGTH; i++) { n_total += 1; } } //使用mutex互斥鎖 void test_f_mutex() { for(int i = 0; i < TEST_DATA_LENGTH; i++) { m.lock(); m_total += 1; m.unlock(); } } //使用原子操作 void test_f_atomic() { for(int i = 0; i < TEST_DATA_LENGTH; i++) { a_total += 1; } } void main() { thread ts[THREAD_NUM]; //normal mode ,result is error clock_t start = clock(); for(int i = 0; i < THREAD_NUM; i++) { ts[i] = thread(&test_f_normal); } for(int i = 0; i < THREAD_NUM; i++) { ts[i].join(); } clock_t end = clock(); cout << "total: " << n_total << endl; cout << "test_f_normal: " << end - start << endl; //use mutex , clock_t mstart = clock(); for(int i = 0; i < THREAD_NUM; i++) { ts[i] = thread(&test_f_mutex); } for(int i = 0; i < THREAD_NUM; i++) { ts[i].join(); } clock_t mend = clock(); cout << "total: " << m_total << endl; cout << "test_f_mutex: " << mend - mstart << endl; //use atomic clock_t astart = clock(); for(int i = 0; i < THREAD_NUM; i++) { ts[i] = thread(&test_f_atomic); } for(int i = 0; i < THREAD_NUM; i++) { ts[i].join(); } clock_t aend = clock(); cout << "total: " << a_total << endl; cout << "test_f_atomic: " << aend - astart << endl; system("pause"); return; }
測試結果
total: 601409 test_f_normal: 29 total: 1000000 test_f_mutex: 11274 total: 1000000 test_f_atomic: 35
總結
由上面的測試結果可以看得出來
1.在不使用互斥鎖和原子量的時候,多線程的操作會使結果是錯誤的.
2.原子操作的實現跟普通數據類型類似,但是它能夠在保證結果正確的前提下,提供比mutex等鎖機制更好的性能
提示:開發過程中,對於多線程的情況下,單個基礎數據類型的數據共享安全,盡量使用原子操作代替鎖機制. 當需要對代碼塊進行數據安全保護的時候,就需要選擇使用鎖機制或者自旋鎖了。