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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

原子操作概述

發布時間:2025/4/5 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 原子操作概述 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

有一件事情,你不得不承認,C語言相對匯編來說是高級語言,為什么,因為高級語言會形成封裝,比如,我需要把一個變量A++,對于CPU來說,先從內存里把這個變量讀進運算寄存器,然后運算增加,然后再把A寫入原來的內存位置。

?

什么是原子操作?

不被其他事件打斷的操作,就叫做原子操作。

老外是用這樣一句話來說明這個

“Do this, and don’t get interrupted while doing this.”

?

我們在CPU里面,想把A++,執行一次,因為是C語言實現的,所以這個指令會被編譯成匯編語言,變成了好幾個指令,比如CPU從內存中拿A到寄存器里面,這個操作,就可能被其他事件打斷,有可能是中斷,也可能是定時器,也有可能是CPU線程調度等其他原因。

為什么我們要討論原子操作?

如果沒有多線程編程的同學,應該對這個沒概念,也不會知道這個會引起什么問題,這樣好了,我來寫一個例子。

#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h> #include <sys/syscall.h> #define gettidv1() syscall(__NR_gettid) #define gettidv2() syscall(SYS_gettid) long int NUM = 0; void * th(void * ptr) { int i = 0; for(i = 0;i < 1000000000;i++) { NUM++; } //sleep(1); //printf("IM %s ID:%ld number:%ld\n",(char*)ptr,gettidv1(),NUM); } int main(int argc,char ** argv) { pthread_t thread1 = -1; if(pthread_create(&thread1,NULL,th,"th1")!=0) { printf("thread1 creat error\n"); } pthread_t thread2 = -1; if(pthread_create(&thread2,NULL,th,"th2")!=0) { printf("thread1 creat error\n"); } while(1) { printf("IM %s ID:%ld number:%ld\n","Main",gettidv1(),NUM); sleep(2); }; }

?

Makefile文件

all: gcc thread.c -o thread -pthread clean: rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions

輸出結果

linux@ubuntu:~/linuxBook/linux-c/pthread$ make && ./thread gcc thread.c -o thread -pthread IM Main ID:7503 number:0 IM Main ID:7503 number:638925977 IM Main ID:7503 number:1334751130 IM Main ID:7503 number:1997474779

?

總結下原因

我相信很多人應該看過類似的例子,但是可能沒有自己去寫過,而且可能寫的時候,給的變量比較小,就有可能導致看到的結果不一樣。

我說下原因,因為NUM++ ,這個操作不是原子的,就是說他在干活的時候,有可能被其他東西打斷。

?

線程1在執行第一步的時候,CPU的控制器被調度給線程2使用了,然后呢,線程2 就做自己的事情,把NUM運算成1了,然后CPU控制權又回來到線程1這里,因為線程1剛才上一次的運算還沒有完成,他就繼續用原來寄存器里面的數據進行運算,然后NUM最后還是1。

可以看到一個問題的是,線程2的這次操作被忽略了,實際上他打工干活了,但是包工頭沒有給他記賬,結果后面結賬的時候,也沒有給他工錢,這個就比較悲劇了。

在單核CPU上應該很好理解,但是在多核上要費點心思,SMP加上L1,L2緩存后,處理變得很復雜。

之前文章有點長,以后還是簡化文章,覺得不錯,支持一下。

總結

以上是生活随笔為你收集整理的原子操作概述的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。