背景知識(shí):
線程 (thread) 線程指代可執(zhí)行代碼的一部分
進(jìn)程 (process) 指代可執(zhí)行代碼,可以包含多個(gè)線程
線程間同步的目的
解決多個(gè)線程讀寫同一個(gè)數(shù)據(jù)時(shí),造成的數(shù)據(jù)錯(cuò)亂問題
線程間同步的方式
- 互斥鎖 (Mutex)
- 目的:保證同一時(shí)刻只有一段代碼進(jìn)入臨界區(qū)進(jìn)行操作。
- 做法:
- 第一段代碼進(jìn)入臨界區(qū)之后,執(zhí)行加鎖操作。
- 進(jìn)入臨界區(qū)之前檢查鎖變量的bool值,如果為false則會(huì)放棄cpu等待進(jìn)入掛起狀態(tài),保存上下文切換部分。
- 直到鎖的狀態(tài)發(fā)生改變時(shí)再喚醒,線程激活進(jìn)行恢復(fù)上下文。
- 問題:由于存儲(chǔ)、恢復(fù)上下文會(huì)帶來(lái)一定的開銷,不要在性能敏感的地方使用
- 自旋鎖 (spinlock)
- 目的:為了節(jié)約互斥鎖存儲(chǔ)恢復(fù)上下文的造成的開銷。
- 做法:線程反復(fù)檢查鎖變量是否可用。
while (搶鎖(lock)==沒搶到) {
}
- 問題: 會(huì)造成忙等待。
- 信號(hào)量 (Semaphore)
- 目的:不需要使用忙等待的方法。在信號(hào)量只有0或1的時(shí)候就是互斥鎖。
- 做法:
- 創(chuàng)建一個(gè)同步對(duì)象作為信號(hào)量,該計(jì)數(shù)值范圍為0到最大值。
- 線程對(duì)信號(hào)量等待 (wait) 時(shí),計(jì)數(shù)值減一;線程對(duì)信號(hào)量釋放 (release) 時(shí),計(jì)數(shù)值加一。
會(huì)出現(xiàn)的問題
- 死鎖 (deadlock)
- 出現(xiàn)時(shí)機(jī): 兩個(gè)以上的線程,雙方都在等待對(duì)方停止運(yùn)行,以繼續(xù)運(yùn)行,但沒有一方提前退出。

死鎖示例:P1、P2兩個(gè)進(jìn)程都需要有R1、R2兩個(gè)資源才能繼續(xù)運(yùn)行。P1擁有R2,需要R1才能繼續(xù)運(yùn)行;P2擁有R1,需要R2才能繼續(xù)運(yùn)行。都在互相等待,導(dǎo)致死鎖。
- 數(shù)據(jù)競(jìng)爭(zhēng) (race hazard)
- 出現(xiàn)時(shí)機(jī):兩個(gè)進(jìn)程同時(shí)修改一個(gè)共享內(nèi)容,沒有并發(fā)控制的情況下,最后結(jié)果依賴于進(jìn)程的執(zhí)行順序。并有可能會(huì)發(fā)生并發(fā)訪問沖突。
參考文章
互斥鎖,同步鎖,臨界區(qū),互斥量,信號(hào)量,自旋鎖之間聯(lián)系是什么?
信號(hào)量wiki
死鎖wiki
數(shù)據(jù)競(jìng)爭(zhēng)wiki