【Linux】死鎖!!!

死鎖概念
在多線程程序裏面多個線程因爲競爭資源而產生的僵持現象。

產生死鎖的四個條件

  • 互斥條件:每個資源每次只能被一個進程使用,即在一度那時間內得某資源僅爲一個進程所佔有。此時若有其他的進程請求該資源,則請求進程只能等待。
  • 請求與保持條件:進程已經保持了至少一個資源,但是又提出來新的資源請求,而該資源已經被其他的進程戰友,此時請求進程被阻塞,但自己已獲得的資源保持不放
  • 不可剝奪條件:進程獲得的資源在未使用完畢之前,不能被其他進程隨意強行奪走,即獲得的資源只能夠由自己釋放。
  • 循環等待條件:若干進程間形成首尾相接循環等待資源的關係。

例如:線程A對資源加鎖,但是在A釋放鎖之前又再次申請同一個資源。
情況1:

pthread_mutex_t lock;

void* pthread_run(void* arg){
    pthread_mutex_lcok(&lock);
    printf("pthread_run\n");
    pthread_mutex_lcok(&lock);
    printf("pthread_run\n");
    pthread_mutex_unlcok(&lock);
}

int main(){
    pthread_t tid;
    pthread_mutex_init(&lock,NULL);
    pthread_create(&tid,NULL,pthread_run,NULL);

    printf("Main pthread is join!\n");
    pthread_join(tid,NULL);
    return 0;
}

兩個線程間互相等待對方的資源,導致死鎖。
情況2:


pthread_cond_t cond1,cond2;
pthread_mutex_t lock;

void* pthread_run1(void* arg){
    pthread_mutex_lock(&lock);
    pthread_cond_wait(&cond2,&lock);
    printf("pthread_run\n");
    pthread_mutex_unlock(&lock);
}
void* pthread_run2(void* arg){
    pthread_mutex_lock(&lock);
    pthread_cond_wait(&cond1,&lock);
    printf("pthread_run\n");
    pthread_mutex_unlock(&lock);
}
int main(){
    pthread_t tid1,tid2;
    pthread_mutex_init(&lock,NULL);
    pthread_cond_init(&cond2,NULL);
    pthread_cond_init(&cond1,NULL);
    pthread_create(&tid1,NULL,pthread_run1,NULL);
    pthread_create(&tid2,NULL,pthread_run2,NULL);

    printf("Main pthread is join!\n");
    pthread_join(tid1,NULL);
    pthread_join(tid2,NULL);
    return 0;
}

如何避免死鎖

1.破壞“互斥”條件:就是在系統裏取消互斥。若資源不被一個進程獨佔使用,那麼死鎖是肯定不會發生的。但一般來說在所列的四個條件中,“互斥”條件是無法破壞的。因此,在死鎖預防裏主要是破壞其他幾個必要條件,而不去涉及破壞“互斥”條件。

2.破壞“佔有並等待”條件:破壞“佔有並等待”條件,就是在系統中不允許進程在已獲得某種資源的情況下,申請其他資源。即要想出一個辦法,阻止進程在持有資源的同時申請其他資源。

方法一:創建進程時,要求它申請所需的全部資源,系統或滿足其所有要求,或什麼也不給它。這是所謂的 “ 一次性分配”方案。
方法二:要求每個進程提出新的資源申請前,釋放它所佔有的資源。這樣,一個進程在需要資源S時,須先把它先前佔有的資源R釋放掉,然後才能提出對S的申請,即使它可能很快又要用到資源R。

3.破壞“不可搶佔”條件:破壞“不可搶佔”條件就是允許對資源實行搶奪。
方法一:如果佔有某些資源的一個進程進行進一步資源請求被拒絕,則該進程必須釋放它最初佔有的資源,如果有必要,可再次請求這些資源和另外的資源。
方法二:如果一個進程請求當前被另一個進程佔有的一個資源,則操作系統可以搶佔另一個進程,要求它釋放資源。只有在任意兩個進程的優先級都不相同的條件下,方法二才能預防死鎖。

4.破壞“循環等待”條件:破壞“循環等待”條件的一種方法,是將系統中的所有資源統一編號,進程可在任何時刻提出資源申請,但所有申請必須按照資源的編號順序(升序)提出。這樣做就能保證系統不出現死鎖。

發佈了89 篇原創文章 · 獲贊 75 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章