成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

線程同步與互斥(死鎖的避免)

臨界資源:

樂(lè)山網(wǎng)站制作公司哪家好,找成都創(chuàng)新互聯(lián)!從網(wǎng)頁(yè)設(shè)計(jì)、網(wǎng)站建設(shè)、微信開(kāi)發(fā)、APP開(kāi)發(fā)、成都響應(yīng)式網(wǎng)站建設(shè)等網(wǎng)站項(xiàng)目制作,到程序開(kāi)發(fā),運(yùn)營(yíng)維護(hù)。成都創(chuàng)新互聯(lián)自2013年創(chuàng)立以來(lái)到現(xiàn)在10年的時(shí)間,我們擁有了豐富的建站經(jīng)驗(yàn)和運(yùn)維經(jīng)驗(yàn),來(lái)保證我們的工作的順利進(jìn)行。專(zhuān)注于網(wǎng)站建設(shè)就選成都創(chuàng)新互聯(lián)。

一個(gè)進(jìn)程的資源對(duì)于運(yùn)行在它內(nèi)部的線程是共享的,一次只允許一個(gè)線程使用的資源叫做臨界資源

臨界區(qū):

訪問(wèn)臨界資源的那段程序叫做臨界區(qū)

線程的同步:

同步就是協(xié)同步調(diào),按照預(yù)定的先后順序執(zhí)行。

“同”字應(yīng)是指協(xié)同、協(xié)助、互相配合。

線程的互斥:

某一資源同時(shí)只允許一個(gè)訪問(wèn)者對(duì)其進(jìn)行訪問(wèn),具有唯一性和排它性。

但互斥無(wú)法限制訪問(wèn)者對(duì)資源的訪問(wèn)順序,即訪問(wèn)是無(wú)序的。

互斥量(mutex)

多個(gè)線程同時(shí)訪問(wèn)共享數(shù)據(jù)時(shí),經(jīng)常會(huì)發(fā)生沖突,因此常常引入互斥鎖來(lái)解決這個(gè)問(wèn)題。

沖突:例如對(duì)一個(gè)全局變量g_var進(jìn)行加一操作,這樣的操作需要三條指令來(lái)完成:(1、把該變量的值從內(nèi)存讀到寄存器;2、寄存器進(jìn)行加一操作;3、把修改后的值寫(xiě)回內(nèi)存),因?yàn)檫@三條指令的執(zhí)行不是原子操作,有可能線程1執(zhí)行了第一步(把變量值讀到寄存器),此時(shí)內(nèi)核調(diào)度線程2,線程2也把該值讀到寄存器,它們都進(jìn)行加一操作后寫(xiě)回內(nèi)存,導(dǎo)致最后結(jié)果只加了一次,而我們希望是兩次。

解決:引入互斥鎖,獲得鎖的線程可以對(duì)變量進(jìn)行“讀-修改-寫(xiě)”操作,這個(gè)操作是原子的,完成這個(gè)操作后釋放鎖給別的線程,沒(méi)有獲得鎖的線程只能等待而不能訪問(wèn)該共享數(shù)據(jù)。

有關(guān)函數(shù):

1.互斥鎖的初始化及銷(xiāo)毀

其中初始化既可以使用函數(shù)pthread_mutex_init(),也可以定義pthread_mutex_t類(lèi)型的變量mutex,并賦值PTHREAD_MUTEX_INITIALIZER

線程同步與互斥(死鎖的避免)

線程同步與互斥(死鎖的避免)

2.對(duì)mutex的加鎖及解鎖

一個(gè)線程可以調(diào)用pthread_mutex_lock獲得Mutex,如果這時(shí)另一個(gè)線程已經(jīng)調(diào)用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ì)使線程掛起等待。

線程同步與互斥(死鎖的避免)

線程同步與互斥(死鎖的避免)


Mutex的lock和unlock的偽碼(以x86的xchg指令為例):

線程同步與互斥(死鎖的避免)

不使用互斥量代碼:

#include <stdio.h>
#include <pthread.h>

void *thread(void *arg)
{
    int count=2000;
    while(count-- >0){
        int var=g_var;
        printf("this is thread%d,g_var=%d\n",(int)arg,g_var);
        g_var=var+1;
    }
}

int main()
{
    pthread_t tid1,tid2;
    
    if(pthread_create(&tid1,NULL,thread,(void*)1)!=0){
        printf("creat tid1 is failed\n");
    }
    if(pthread_create(&tid1,NULL,thread,(void*)2)!=0){
        printf("creat tid1 is failed\n");
    }
    pthread_join(tid1,NULL);
    pthread_join(tid2,NULL);
    
    return 0;
}

運(yùn)行結(jié)果:

第一次運(yùn)行線程1和線程2一共加了2275次

線程同步與互斥(死鎖的避免)

第二次運(yùn)行一共把g_var加了2000次

線程同步與互斥(死鎖的避免)

使用互斥量實(shí)現(xiàn)代碼:

include <stdio.h>
#include <pthread.h>

//pthread_mutex_t mutex_lock=PTHREAD_MUTEX_INITIALIZER;

struct info
{
    int _var;
    pthread_mutex_t  *_mutex_lock;
}info;

int g_var=0;
void *thread(void *arg)
{
    struct info* _lock=(struct info*)arg;
    int count=2000;
    while(count-- >0){
        pthread_mutex_lock(_lock->_mutex_lock);
        int var=g_var;
        printf("this is thread%d,g_var=%d\n",_lock->_var,g_var);
        g_var=var+1;
        pthread_mutex_unlock(_lock->_mutex_lock);
    }   
}

int main()
{
    pthread_t tid1,tid2;
    pthread_mutex_t mutex_lock;
    int err=pthread_mutex_init(&mutex_lock,NULL);
    if(err!=0){
        printf("%s\n",strerror(err));
    }

    struct info info1;
    info1._var=1;
    info1._mutex_lock=&mutex_lock;

    if(pthread_create(&tid1,NULL,thread,&info1)!=0){
        printf("creat tid1 is failed\n");
    }

    struct info info2;
    info2._var=2;
    info2._mutex_lock=&mutex_lock;

    if(pthread_create(&tid2,NULL,thread,&info2)!=0){
        printf("creat tid2 is failed\n");
    }
    
    pthread_join(tid1,NULL);
    pthread_join(tid2,NULL);

    err=pthread_mutex_destroy(&mutex_lock);
    if(err!=0){
        printf("%s\n",strerror(err));
    }

    return 0;
}

運(yùn)行結(jié)果:

線程1和線程2共執(zhí)行了4000次

線程同步與互斥(死鎖的避免)

總結(jié):當(dāng)一個(gè)線程已經(jīng)獲得鎖,另一個(gè)線程需掛起等待,當(dāng)該線程釋放鎖后,會(huì)喚醒正在等待線程。每個(gè)mutex都有一個(gè)等待隊(duì)列,當(dāng)線程掛起時(shí),就加入該等待隊(duì)列,狀態(tài)設(shè)置為睡眠。一個(gè)線程要喚醒別的線程,只需要從等待隊(duì)列中取出一項(xiàng)加入就緒隊(duì)列并把它的狀態(tài)設(shè)置為就緒。

有的時(shí)候一個(gè)線程會(huì)兩次獲得鎖,第一次正常獲得,第二次獲得所得時(shí)候發(fā)現(xiàn)鎖已經(jīng)被別占用,它就會(huì)掛起,導(dǎo)致自己占用了鎖卻處于掛起狀態(tài),這樣就產(chǎn)生了死鎖。

死鎖:

產(chǎn)生死鎖的原因

1、進(jìn)程資源不足

2、進(jìn)程推進(jìn)的順序不合適

3、系統(tǒng)資源的分配不當(dāng)

產(chǎn)生死鎖的必要條件:

1、互斥條件:一個(gè)資源一次只能被一個(gè)進(jìn)程使用

2、請(qǐng)求與保持條件:一個(gè)已經(jīng)進(jìn)程因請(qǐng)求資源而阻塞,對(duì)已獲得的資源保持不放

3、不剝奪條件:進(jìn)程已獲得的資源,在沒(méi)使用完之前,不能強(qiáng)行剝奪

4、循環(huán)等待條件:若干個(gè)進(jìn)程之間形成一種頭尾相接的循環(huán)等待資源關(guān)系

產(chǎn)生死鎖時(shí),以上四個(gè)必要條件一定都成立。



網(wǎng)頁(yè)名稱:線程同步與互斥(死鎖的避免)
瀏覽路徑:http://jinyejixie.com/article8/ijdgop.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供虛擬主機(jī)、App設(shè)計(jì)、搜索引擎優(yōu)化、網(wǎng)頁(yè)設(shè)計(jì)公司、關(guān)鍵詞優(yōu)化、營(yíng)銷(xiāo)型網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

商城網(wǎng)站建設(shè)
涪陵区| 宁波市| 山东| 三原县| 鄂托克旗| 鹤山市| 镇沅| 泰安市| 济源市| 通城县| 教育| 维西| 东乌珠穆沁旗| 岳阳市| 尤溪县| 济南市| 连云港市| 博罗县| 栾川县| 绥棱县| 华池县| 扬中市| 大厂| 垦利县| 松潘县| 阜新市| 平昌县| 高尔夫| 涿鹿县| 大同县| 临湘市| 金阳县| 台湾省| 梅河口市| 濮阳县| 利川市| 石首市| 安义县| 霞浦县| 大港区| 合水县|