线程同步之——互斥量及死锁问题
互斥量:
多個線程同時訪問共享數(shù)據(jù)時可能會沖突,這跟信號的可重性是同樣的問題。如 果兩個線程都要把某個全局變量增加1,這個操作在某平臺需要三條指令完成:
1. 從內(nèi)存讀變量值到寄存器
2. 寄存器的值加1
3. 將寄存器的值寫回內(nèi)存
先舉個例子:創(chuàng)建兩個線程,各把counter增加5000次,正常情況下最后counter應(yīng)該等于10000。
代碼實現(xiàn)如下:
結(jié)果:
可以看到,每次運行程序的結(jié)果都不一樣。說明在調(diào)用過程中發(fā)生了互斥現(xiàn)象。
解決辦法:加互斥鎖
實現(xiàn)多線程同步可以引互斥鎖(Mutex,Mutual Exclusive Lock),獲得鎖的線程可以完成“讀-修改-寫”的操作,然后釋放鎖給其它線程,沒有獲得鎖的線程只能等待不能訪問共享數(shù)據(jù),這樣“讀-修改-寫”三步操作組成個原操作,要么都執(zhí),要么都不執(zhí),不會執(zhí)到中間被打斷,也不會在其它處理器上并做這個操作。 Mutexpthread_mutex_t類型的變量表,可以這樣初始化和銷毀。
相關(guān)函數(shù)如下:
pthread_mutex_init函 數(shù)初始化的Mutex可以pthread_mutex_destroy銷毀。 如果Mutex變量是靜態(tài)分配的(全局變量 或static變量),也可以宏定義PTHREAD_MUTEX_INITIALIZER來初始化,相當于 pthread_mutex_init初始化并且attr參數(shù)為NULL。 Mutex的加鎖和解鎖操作可以下列函數(shù)
一個線程可以調(diào)pthread_mutex_lock獲得Mutex,如果這時另一個線程已經(jīng)調(diào)pthread_mutex_lock獲得了該Mutex,則當前線程需要掛起等待,直到另一個線程調(diào)pthread_mutex_unlock釋放Mutex,當前線程被喚醒,才能獲得該Mutex并繼續(xù)執(zhí)。如果這個線程既想獲得鎖,又不想掛起等待,可以調(diào)pthread_mutex_trylock,如果Mutex已經(jīng)被 另一個線程獲得,這個函數(shù)會失敗返回EBUSY,不會使線程掛起等待。
現(xiàn)在給上一個例子加上互斥鎖,代碼如下:
運行結(jié)果如下:
可以看到,加鎖后實現(xiàn)了線程同步。
死鎖原理:
根據(jù)操作系統(tǒng)中的定義:死鎖是指在一組進程中的各個進程均占有不會釋放的資源,但因互相申請被其他進程所占用不會釋放的資源而處于的一種永久等待狀態(tài)。
死鎖的四個必要條件:
1、互斥條件(Mutual exclusion):資源不能被共享,只能由一個進程使用。
2、請求與保持條件(Hold and wait):已經(jīng)得到資源的進程可以再次申請新的資源。
3、非剝奪條件(No pre-emption):已經(jīng)分配的資源不能從相應(yīng)的進程中被強制地剝奪。
4、循環(huán)等待條件(Circular wait):系統(tǒng)中若干進程組成環(huán)路,該環(huán)路中每個進程都在等待相鄰進程正占用的資源
解決死鎖的基本方法:
1、預防死鎖:
資源一次性分配:(破壞請求和保持條件)
可剝奪資源:即當某進程新的資源未滿足時,釋放已占有的資源(破壞不可剝奪條件)。
資源有序分配法:系統(tǒng)給每類資源賦予一個編號,每一個進程按編號遞增的順序請求資源,釋放則相反(破壞環(huán)路等待條件)。?
2、避免死鎖:
預防死鎖的幾種策略,會嚴重地損害系統(tǒng)性能。因此在避免死鎖時,要施加較弱的限制,從而獲得較滿意的系統(tǒng)性能。由于在避免死鎖的策略中,允許進程動態(tài)地申請資源。因而,系統(tǒng)在進行資源分配之前預先計算資源分配的安全性。若此次分配不會導致系統(tǒng)進入不安全狀態(tài),則將資源分配給進程;否則,進程等待。其中最具有代表性的避免死鎖算法是銀行家算法。?
3、檢測死鎖
首先為每個進程和每個資源指定一個唯一的號碼;
然后建立資源分配表和進程等待表。
4、解除死鎖:
當發(fā)現(xiàn)有進程死鎖后,便應(yīng)立即把它從死鎖狀態(tài)中解脫出來,常采用的方法有:
剝奪資源:從其它進程剝奪足夠數(shù)量的資源給死鎖進程,以解除死鎖狀態(tài);
撤消進程:可以直接撤消死鎖進程或撤消代價最小的進程,直至有足夠的資源可用,死鎖狀態(tài).消除為止;所謂代價是指優(yōu)先級、運行代價、進程的重要性和價值等。
?
?
轉(zhuǎn)載于:https://blog.51cto.com/760470897/1766881
總結(jié)
以上是生活随笔為你收集整理的线程同步之——互斥量及死锁问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 推荐!Sublime Text 最佳插件
- 下一篇: CentOS7搭建lamp(module