您好,登錄后才能下訂單哦!
一:概述
項(xiàng)目中經(jīng)常用遇到多線程操作共享數(shù)據(jù)問(wèn)題,常用的處理方式是對(duì)共享數(shù)據(jù)進(jìn)行加鎖,如果多線程操作共享變量也同樣采用這種方式。
為什么要對(duì)共享變量加鎖或使用原子操作?如兩個(gè)線程操作同一變量過(guò)程中,一個(gè)線程執(zhí)行過(guò)程中可能被內(nèi)核臨時(shí)掛起,這就是線程切換,當(dāng)內(nèi)核再次切換到該線程時(shí),之前的數(shù)據(jù)可能已被修改,不能保證原子操作。
C++11提供了個(gè)原子的類和方法atomic,保證了多線程對(duì)變量原子性操作,相比加鎖機(jī)制mutex.lock(),mutex.unlock(),性能有幾倍的提升。
所需頭文件<atomic>
二:錯(cuò)誤代碼
//全局變量 int g_num = 0; void fun() { for (int i = 0; i < 10000000; i++) { g_num++; } return ; } int main() { //創(chuàng)建線程1 thread t1(fun); //創(chuàng)建線程2 thread t2(fun); t1.join(); t2.join(); cout << g_num << endl; getchar(); return 1; }
應(yīng)該輸出結(jié)果20000000,實(shí)際每次結(jié)果都不一樣,總是小于該值,正是由于多線程操作同一變量而沒(méi)有保證原子性導(dǎo)致的。
三:加鎖代碼
//全局變量 int g_num = 0; mutex m_mutex; void fun() { for (int i = 0; i < 10000000; i++) { m_mutex.lock(); g_num++; m_mutex.unlock(); } return ; } int main() { //獲取當(dāng)前毫秒時(shí)間戳 typedef chrono::time_point<chrono::system_clock, chrono::milliseconds> microClock_type; microClock_type tp1 = chrono::time_point_cast<chrono::milliseconds>(chrono::system_clock::now()); long long time1 = tp1.time_since_epoch().count(); //創(chuàng)建線程 thread t1(fun); thread t2(fun); t1.join(); t2.join(); cout << "總數(shù):" << g_num << endl; //獲取當(dāng)前毫秒時(shí)間戳 microClock_type tp2 = chrono::time_point_cast<chrono::milliseconds>(chrono::system_clock::now()); long long time2 = tp2.time_since_epoch().count(); cout << "耗時(shí):" << time2 - time1 << "ms" << endl; getchar(); return 1; }
執(zhí)行結(jié)果:多次測(cè)試輸出均為20000000,耗時(shí)在3.8s左右
四:atomic原子操作代碼
//全局變量 atomic<int> g_num = 0; void fun() { for (int i = 0; i < 10000000; i++) { g_num++; } return ; } int main() { //獲取當(dāng)前毫秒時(shí)間戳 typedef chrono::time_point<chrono::system_clock, chrono::milliseconds> microClock_type; microClock_type tp1 = chrono::time_point_cast<chrono::milliseconds>(chrono::system_clock::now()); long long time1 = tp1.time_since_epoch().count(); //創(chuàng)建線程 thread t1(fun); thread t2(fun); t1.join(); t2.join(); cout << "總數(shù):" << g_num << endl; //獲取當(dāng)前毫秒時(shí)間戳 microClock_type tp2 = chrono::time_point_cast<chrono::milliseconds>(chrono::system_clock::now()); long long time2 = tp2.time_since_epoch().count(); cout << "耗時(shí):" << time2 - time1 << "ms" << endl; getchar(); return 1; }
執(zhí)行結(jié)果:多次測(cè)試輸出均為20000000,耗時(shí)在1.3s左右
五:小結(jié)
c++11的原子類atomic相比使用加鎖機(jī)制性能有2~3倍提升,對(duì)于共享變量能用原子類型的就不要再用加鎖機(jī)制了。
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)億速云的支持。如果你想了解更多相關(guān)內(nèi)容請(qǐng)查看下面相關(guān)鏈接
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。