背景知識:
線程 (thread) 線程指代可執(zhí)行代碼的一部分
進程 (process) 指代可執(zhí)行代碼论颅,可以包含多個線程
線程間同步的目的
解決多個線程讀寫同一個數(shù)據(jù)時很泊,造成的數(shù)據(jù)錯亂問題
線程間同步的方式
- 互斥鎖 (Mutex)
- 目的:保證同一時刻只有一段代碼進入臨界區(qū)進行操作。
- 做法:
- 第一段代碼進入臨界區(qū)之后苦蒿,執(zhí)行加鎖操作殴胧。
- 進入臨界區(qū)之前檢查鎖變量的bool值,如果為false則會放棄cpu等待進入掛起狀態(tài)刽肠,保存上下文切換部分溃肪。
- 直到鎖的狀態(tài)發(fā)生改變時再喚醒,線程激活進行恢復上下文音五。
- 問題:由于存儲、恢復上下文會帶來一定的開銷羔沙,不要在性能敏感的地方使用
- 自旋鎖 (spinlock)
- 目的:為了節(jié)約互斥鎖存儲恢復上下文的造成的開銷躺涝。
- 做法:線程反復檢查鎖變量是否可用。
while (搶鎖(lock)==沒搶到) {
}
- 問題: 會造成忙等待。
- 信號量 (Semaphore)
- 目的:不需要使用忙等待的方法坚嗜。在信號量只有0或1的時候就是互斥鎖夯膀。
- 做法:
- 創(chuàng)建一個同步對象作為信號量,該計數(shù)值范圍為0到最大值苍蔬。
- 線程對信號量等待 (wait) 時诱建,計數(shù)值減一;線程對信號量釋放 (release) 時碟绑,計數(shù)值加一俺猿。
會出現(xiàn)的問題
- 死鎖 (deadlock)
- 出現(xiàn)時機: 兩個以上的線程,雙方都在等待對方停止運行格仲,以繼續(xù)運行押袍,但沒有一方提前退出。
死鎖示例:P1凯肋、P2兩個進程都需要有R1谊惭、R2兩個資源才能繼續(xù)運行。P1擁有R2侮东,需要R1才能繼續(xù)運行圈盔;P2擁有R1,需要R2才能繼續(xù)運行悄雅。都在互相等待药磺,導致死鎖。
- 數(shù)據(jù)競爭 (race hazard)
- 出現(xiàn)時機:兩個進程同時修改一個共享內容煤伟,沒有并發(fā)控制的情況下癌佩,最后結果依賴于進程的執(zhí)行順序。并有可能會發(fā)生并發(fā)訪問沖突便锨。
參考文章
互斥鎖围辙,同步鎖,臨界區(qū)放案,互斥量姚建,信號量,自旋鎖之間聯(lián)系是什么吱殉?
信號量wiki
死鎖wiki
數(shù)據(jù)競爭wiki