日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > linux >内容正文

linux

int linux 原子操作_linux c++编程之多线程:原子操作如何解决线程冲突

發(fā)布時(shí)間:2023/12/20 linux 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 int linux 原子操作_linux c++编程之多线程:原子操作如何解决线程冲突 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

在多線程中操作全局變量一般都會(huì)引起線程沖突,為了解決線程沖突,引入原子操作。

1.線程沖突

#include #include #include #include int g_count = 0;void count(void *p){Sleep(100); //do some work//每個(gè)線程把g_count加1共10次for (int i = 0; i < 10; i++){g_count++;}Sleep(100); //do some work}int main(void){printf("******多線程訪問(wèn)全局變量演示***by David***");//共創(chuàng)建10個(gè)線程HANDLE handles[10];for (int i = 0; i < 10; i++){for (int j = 0; j < 10; j++){handles[j] = _beginthread(count, 0, NULL);}WaitForMultipleObjects(10, handles, 1, INFINITE);printf("%d time g_count = %d", i, g_count);//重置g_count = 0;}getchar();return 0;}

運(yùn)行

理論上,g_count的最后結(jié)果應(yīng)該是100,可事實(shí)卻并非如此,不但結(jié)果不一定是100,而且每次的結(jié)果還很可能不一樣。原因是,多個(gè)線程對(duì)同一個(gè)全局變量進(jìn)行訪問(wèn)時(shí),特別是在進(jìn)行修改操作,會(huì)引起沖突。詳細(xì)解釋:

設(shè)置斷點(diǎn),查看反匯編

g_count++;被分為三步操作:

1.把g_count的內(nèi)容從內(nèi)存中移動(dòng)到寄存器eax

2.把寄存器eax加1

3.把寄存器eax中的內(nèi)容移動(dòng)到內(nèi)存g_count的地址

三步以后,g_count的值被順利加1。

cpu執(zhí)行的時(shí)間片內(nèi)包含多條指令,每條指令執(zhí)行期間不會(huì)被打斷,但如果一個(gè)操作包含多條指令,則很有可能該操作會(huì)被打斷。g_count++;就是這樣的操作。

g_count被順利加到100的前提:每次加1,都建立在上一次加1順利完成的基礎(chǔ)上。也就是說(shuō),如果上一次加1被打斷,這一次的加1就得不到上一次加1的累積效果。自然,最后的結(jié)果,多半會(huì)小于100。

2.原子操作

所謂原子操作,是指不會(huì)被線程調(diào)度機(jī)制打斷的操作,操作一旦開(kāi)始,就得執(zhí)行到結(jié)束為止。原子操作可以是一個(gè)步驟,也可以是多個(gè)操作步驟,但是其順序是不可以被打亂,或者切割掉只執(zhí)行部分。原子操作一般靠底層匯編實(shí)現(xiàn)。

在頭文件winnt.h中提供了很多的原子操作函數(shù),它們使用自加鎖的方式,保證操作的原子性,如自增操作

InterlockedIncrement,

函數(shù)原型

LONG CDECL_NON_WVMPURE InterlockedIncrement(
_Inout_ _Interlocked_operand_ LONG volatile *Addend
);

其它相關(guān)操作,請(qǐng)自行查看頭文件。

使用該函數(shù),我們修改線程函數(shù)count。修改很簡(jiǎn)單,只需把g_count++改為InterlockedIncrement((LONG)&g_count);即可。

運(yùn)行如下

顯然,在原子操作下,我們肯定是可以得到正確結(jié)果的。

需要C/C++ Linux服務(wù)器架構(gòu)師學(xué)習(xí)資料私信“資料”(資料包括C/C++,Linux,golang技術(shù),Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒體,CDN,P2P,K8S,Docker,TCP/IP,協(xié)程,DPDK,ffmpeg等),免費(fèi)分享

總結(jié)

以上是生活随笔為你收集整理的int linux 原子操作_linux c++编程之多线程:原子操作如何解决线程冲突的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。