線程的同步與互斥
創(chuàng)新互聯(lián)專(zhuān)注于企業(yè)營(yíng)銷(xiāo)型網(wǎng)站建設(shè)、網(wǎng)站重做改版、三原網(wǎng)站定制設(shè)計(jì)、自適應(yīng)品牌網(wǎng)站建設(shè)、H5建站、成都商城網(wǎng)站開(kāi)發(fā)、集團(tuán)公司官網(wǎng)建設(shè)、外貿(mào)網(wǎng)站建設(shè)、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁(yè)設(shè)計(jì)等建站業(yè)務(wù),價(jià)格優(yōu)惠性?xún)r(jià)比高,為三原等各大城市提供網(wǎng)站開(kāi)發(fā)制作服務(wù)。多個(gè)線程同時(shí)訪問(wèn)共享數(shù)據(jù)時(shí)可能會(huì)發(fā)生沖突,比如兩個(gè)線程同時(shí)把一個(gè)全局變量加1,結(jié)果可能不是我們所期待的:
我們看這段代碼的執(zhí)行結(jié)果:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
static int g_count=0;
void *thread(void *arg)
{
int index=0;
int tmp=0;
while(index++<5000)
{
tmp=g_count;
printf("this is thread %d,count is :%d\n",(int)arg,tmp);
g_count=tmp+1;
}
}
int main()
{
pthread_t tid1,tid2;
pthread_create(&tid1,NULL,thread,(void*)1);
pthread_create(&tid2,NULL,thread,(void*)2);
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
printf("the final value is %d\n",g_count);
return 0;
}
我們看它的執(zhí)行結(jié)果:
我們創(chuàng)建了兩個(gè)線程,各自把全局變量g_count加了5000次,結(jié)果理論上應(yīng)該是10000,但其實(shí)不然,每次運(yùn)行的結(jié)果都不一樣,證明訪問(wèn)沖突了。為了解決這個(gè)問(wèn)題,我們需引入互斥鎖。獲得鎖的線程可以完成“讀--修改--寫(xiě)”的操作,然后釋放鎖給其他線程,沒(méi)有獲得鎖的線程只能等待,而不能訪問(wèn)共享數(shù)據(jù),這樣“讀--修改--寫(xiě)”散步操作就成了原子操作,要么都執(zhí)行,要么都不執(zhí)行,不會(huì)執(zhí)行到中間而被打斷,這樣就如我們所期待的了。
pthread_mutex_init函數(shù)對(duì)mutex做初始化,它可以被pthread_mutex_destroy銷(xiāo)毀。如果mutex變量是靜態(tài)分配的,也可以用宏定義PTHREAD_MUTEX_INITIALIZER來(lái)初始化,相當(dāng)于pthread_mutex_init初始化并且attr參數(shù)為NULL。
加鎖和解鎖所需函數(shù):
int pthread_mutex_lock(pthread_mutex_t *mutex)
int pthread_mutex_trylock(pthread_mutex_t *mutex)
int pthread_mutex_unlock(pthread_mutex_t *mutex)
成功返回0,失敗返回錯(cuò)誤號(hào)。
一個(gè)線程可以調(diào)用int pthread_mutex_lock獲得mutex,如果這時(shí)候另一個(gè)線程已經(jīng)調(diào)用int pthread_mutex_lock獲得了該mutex,則當(dāng)前線程需要掛起等待,直到另一個(gè)線程調(diào)用pthread_mutex_unlock釋放mutex,當(dāng)前線程被喚醒,才能獲得該mutex并繼續(xù)執(zhí)行。
如果一個(gè)線程既想獲得鎖,又不想掛起等待,可以調(diào)用 pthread_mutex_trylock,如果mutex已經(jīng)被另一個(gè)線程獲得,則這個(gè)函數(shù)會(huì)返回EBUSY,而不會(huì)使線程掛起等待。
知道這些的話(huà),我們重新修改以上代碼:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
static int g_count=0;
pthread_mutex_t mutex_lock=PTHREAD_MUTEX_INITIALIZER;
void *thread(void *arg)
{
int index=0;
int tmp=0;
while(index++<5000)
{
pthread_mutex_lock(&mutex_lock);
tmp=g_count;
printf("this is thread %d,count is :%d\n",(int)arg,tmp);
g_count=tmp+1;
pthread_mutex_unlock(&mutex_lock);
}
}
int main()
{
pthread_t tid1,tid2;
pthread_create(&tid1,NULL,thread,(void*)1);
pthread_create(&tid2,NULL,thread,(void*)2);
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
printf("the final value is %d\n",g_count);
return 0;
}
運(yùn)行結(jié)果如下:
我們可以看到,經(jīng)過(guò)我們加鎖后,最后value的值是我們所期待的10000,加鎖成功,成功實(shí)現(xiàn)了兩個(gè)線程的互斥運(yùn)行。
死鎖產(chǎn)生的原因及四個(gè)必要條件
所謂死鎖,是指多個(gè)進(jìn)程在運(yùn)行過(guò)程中因爭(zhēng)奪資源而造成的一種僵局,當(dāng)進(jìn)程處于這種僵持狀態(tài)時(shí),若無(wú)外力作用,他們都將無(wú)法再向前推進(jìn)。
產(chǎn)生死鎖的主要原因有:
1.系統(tǒng)資源不足;
2.進(jìn)程運(yùn)行推進(jìn)的順序不合適;
3.資源分配不當(dāng)?shù)龋?/p>
如果系統(tǒng)資源充足,進(jìn)程的資源請(qǐng)求都能夠得到滿(mǎn)足,死鎖出現(xiàn)的可能性就降低,否則,就會(huì)因爭(zhēng)奪有限的資源而陷入死鎖。其次,進(jìn)程運(yùn)行推進(jìn)順序與速度不同,也可能產(chǎn)生死鎖。
產(chǎn)生死鎖的四個(gè)必要條件:
1.互斥條件:一個(gè)資源每次只能被一個(gè)進(jìn)程使用;
2.請(qǐng)求與保持條件:一個(gè)進(jìn)程因請(qǐng)求資源而阻塞時(shí),對(duì)已獲得的資源保持不放;
3.不剝奪條件:進(jìn)程已獲得的資源,在使用完之前,不能強(qiáng)行剝奪;
4.循環(huán)等待條件:若干進(jìn)程之間形成一種頭尾相接的循環(huán)等待資源關(guān)系;
以上是產(chǎn)生死鎖的四個(gè)必要條件,只要系統(tǒng)發(fā)生死鎖,這些條件必然成立,而只要上述條件之一不滿(mǎn)足,就不會(huì)發(fā)生死鎖。
處理死鎖的基本方法:
1.預(yù)防死鎖:
該方法是通過(guò)設(shè)置某些限制條件,去破壞產(chǎn)生死鎖四個(gè)必要條件中的一個(gè)或幾個(gè)條件,來(lái)預(yù)防發(fā)生死鎖。
2.避免死鎖
不需事先采取各種限制措施去破壞產(chǎn)生死鎖的四個(gè)必要條件,而是在資源的動(dòng)態(tài)分配過(guò)程中,用某種方法去防止系統(tǒng)進(jìn)入不安全狀態(tài),從而避免發(fā)生死鎖。
3.檢測(cè)死鎖
這種方法不需事先采取任何限制措施,也不必檢查系統(tǒng)是否已經(jīng)進(jìn)入不安全區(qū),而是允許系統(tǒng)在運(yùn)行過(guò)程中發(fā)生死鎖。但可以通過(guò)系統(tǒng)所設(shè)置的檢測(cè)機(jī)構(gòu),及時(shí)的檢測(cè)死鎖的發(fā)生,并精確的確定與死鎖有關(guān)的進(jìn)程資源,然后采取適當(dāng)措施,從系統(tǒng)中將已發(fā)生的死鎖清除掉。
4.解除死鎖
這是與檢測(cè)死鎖相配套的一種措施。當(dāng)檢測(cè)到發(fā)生死鎖時(shí),需將進(jìn)程從死鎖狀態(tài)中解脫出來(lái)。常用的實(shí)施方法是撤消或掛起一些進(jìn)程,以便回收一些資源,再將這些資源分配給已處于阻塞狀態(tài)的進(jìn)程,使之轉(zhuǎn)為就緒狀態(tài),一邊繼續(xù)運(yùn)行。
死鎖的解除與預(yù)防:
理解了死鎖的原因,尤其是產(chǎn)生死鎖的四個(gè)必要條件,就可以大程度的避免,預(yù)防和解除死鎖。所以在系統(tǒng)設(shè)計(jì),進(jìn)程調(diào)度等方面注意如何不讓這四個(gè)必要條件成立,如何確定資源的合理分配算法,避免進(jìn)程永久占用系統(tǒng)資源。此外,也要防止進(jìn)程在處于等待狀態(tài)的情況下占用資源。因此,對(duì)資源的分配要給與合理的規(guī)劃。
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性?xún)r(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專(zhuān)為企業(yè)上云打造定制,能夠滿(mǎn)足用戶(hù)豐富、多元化的應(yīng)用場(chǎng)景需求。
本文標(biāo)題:線程的同步與互斥,死鎖-創(chuàng)新互聯(lián)
轉(zhuǎn)載來(lái)于:http://aaarwkj.com/article26/ccdejg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供域名注冊(cè)、網(wǎng)站改版、響應(yīng)式網(wǎng)站、Google、面包屑導(dǎo)航、網(wǎng)站營(yíng)銷(xiāo)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容