C++11中的原子操作(atomic operation)和自旋锁
C++11中的原子操作(atomic operation)
- 1. 原子操作
- 2. 自旋鎖
- 3. 原子操作和使用互斥鎖和自旋鎖的速度對(duì)比
1. 原子操作
??所謂的原子操作,取的就是“原子是最小的、不可分割的最小個(gè)體”的意義,它表示在多個(gè)線程訪問同一個(gè)全局資源的時(shí)候,能夠確保所有其他的線程都不在同一時(shí)間內(nèi)訪問相同的資源。
??我們?cè)谠硬僮髦霸诙嗑€程同步中防止發(fā)生數(shù)據(jù)競(jìng)爭(zhēng)的操作是加互斥鎖,但互斥鎖是操作系統(tǒng)這一層級(jí)的,最終映射到CPU上也是一堆指令,是指令就必然會(huì)帶來(lái)額外的開銷;既然CPU指令是多線程不可再分的最小單元,那我們?nèi)绻修k法將代碼語(yǔ)句和指令對(duì)應(yīng)起來(lái),不就不需要引入互斥鎖從而提高性能了嗎? 而這個(gè)對(duì)應(yīng)關(guān)系就是所謂的原子操作;
??在新標(biāo)準(zhǔn)C++11,引入了原子操作的概念,并通過這個(gè)新的頭文件提供了多種原子操作數(shù)據(jù)類型,例如,atomic_bool,atomic_int等等,如果我們?cè)诙鄠€(gè)線程中對(duì)這些類型的共享資源進(jìn)行操作,編譯器將保證這些操作都是原子性的,也就是說,確保任意時(shí)刻只有一個(gè)線程對(duì)這個(gè)資源進(jìn)行訪問,編譯器將保證,多個(gè)線程訪問這個(gè)共享資源的正確性。從而避免了鎖的使用,提高了效率。
2. 自旋鎖
??自旋鎖是一種基礎(chǔ)的同步原語(yǔ),用于保障對(duì)共享數(shù)據(jù)的互斥訪問。與互斥鎖的相比,在獲取鎖失敗的時(shí)候不會(huì)使得線程阻塞而是一直自旋嘗試獲取鎖。當(dāng)線程等待自旋鎖的時(shí)候,CPU不能做其他事情,而是一直處于輪詢忙等的狀態(tài)。
??自旋鎖主要適用于被持有時(shí)間短,線程不希望在重新調(diào)度上花過多時(shí)間的情況。實(shí)際上許多其他類型的鎖在底層使用了自旋鎖實(shí)現(xiàn),例如多數(shù)互斥鎖在試圖獲取鎖的時(shí)候會(huì)先自旋一小段時(shí)間,然后才會(huì)休眠。如果在持鎖時(shí)間很長(zhǎng)的場(chǎng)景下使用自旋鎖,則會(huì)導(dǎo)致CPU在這個(gè)線程的時(shí)間片用盡之前一直消耗在無(wú)意義的忙等上,造成計(jì)算資源的浪費(fèi)。
自旋鎖相關(guān)API:
int pthread_spin_init(pthread_spinlock_t *, int); //初始化自旋鎖 int pthread_spin_lock(pthread_spinlock_t *); //獲得一個(gè)自旋鎖 int pthread_spin_trylock(pthread_spinlock_t *); //嘗試獲取一個(gè)自旋鎖 int pthread_spin_unlock(pthread_spinlock_t *);//釋放(解鎖)一個(gè)自旋鎖 int pthread_spin_destroy(pthread_spinlock_t *); //銷毀一個(gè)自旋鎖使用自旋鎖注意:
??由于自旋時(shí)不釋放CPU,因而持有自旋鎖的線程應(yīng)該盡快釋放自旋鎖,否則等待該自旋鎖的線程會(huì)一直在哪里自旋,這就會(huì)浪費(fèi)CPU時(shí)間。
持有自旋鎖的線程在sleep之前應(yīng)該釋放自旋鎖以便其他線程可以獲得該自旋鎖
3. 原子操作和使用互斥鎖和自旋鎖的速度對(duì)比
單線程無(wú)鎖速度最快,但應(yīng)用場(chǎng)合受限;
多線程無(wú)鎖速度第二快,但結(jié)果不對(duì),未保護(hù)臨界代碼段;
多線程原子鎖第三快,且結(jié)果正確;
多線程互斥量較慢,慢與原子鎖近10倍,結(jié)果正確;
多線程自旋鎖最慢,慢與原子鎖30倍,結(jié)果正確。
結(jié)論:原子鎖速度最快,互斥量和自旋鎖都用保護(hù)多線程共享資源。
??自旋鎖是一種非阻塞鎖,也就是說,如果某線程需要獲取自旋鎖,但該鎖已經(jīng)被其他線程占用時(shí),該線程不會(huì)被掛起,而是在不斷的消耗CPU的時(shí)間,不停的試圖獲取自旋鎖。
??互斥量是阻塞鎖,當(dāng)某線程無(wú)法獲取互斥量時(shí),該線程會(huì)被直接掛起,該線程不再消耗CPU時(shí)間,當(dāng)其他線程釋放互斥量后,操作系統(tǒng)會(huì)激活那個(gè)被掛起的線程,讓其投入運(yùn)行。
總結(jié)
以上是生活随笔為你收集整理的C++11中的原子操作(atomic operation)和自旋锁的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 第一次团队合作计划
- 下一篇: VC操作word和excel文件,查询与