二 Linux--多線程( 三 )


死鎖產生的四個必要條件:

  • 互斥條件:一個資源每次只能被一個執行流使用
  • 請求與保持條件:一個執行流因請求資源而阻塞時 , 對已獲得的資源保持不放
  • 不剝奪條件:一個執行流已獲得的資源,在末使用完之前,不能強行剝奪
  • 循環等待條件:若干執行流之間形成一種頭尾相接的循環等待資源的關系
避免死鎖:
  • 破壞請求和保持條件
    • 協議1:所有進程開始前,必須一次性地申請所需的所有資源,這樣運行期間就不會再提出資源的需求,破壞了請求條件,即使有一種資源不能滿足需求,也不會給它分配正在空閑的資源,這樣它就沒有資源,就破壞了保持條件,從而預防死鎖
    • 協議2:允許一個進程只獲得初期的資源就開始運行,然后再把運行完的資源釋放出來,然后再請求新的資源
  • 破壞不可搶占條件
    • 當一個已經保持了某種不可搶占資源的進程 , 提出新資源請求不能被滿足的時候 , 它必須釋放已經保持的所有資源 , 以后需要的時候再申請
  • 破壞循環等待條件
    • 對系統中的所有資源類型進行線性排序,然后規定每個進程必須按序列號遞增的順序請求資源 。加入進程請求到了一些序列號較高的資源,然后請求一個序列號較低的資源時,必須先釋放相同的更高序號的資源后才能申請低序列號的資源,多個同類資源必須一起請求
    • 將所有資源進行線性排序,每個進程申請資源的順序保持一致
實例演示:
#include <stdio.h>#include <pthread.h>#include <unistd.h>//線程的兩個互斥量pthread_mutex_t mutex1;pthread_mutex_t mutex2;//線程1處理函數void *fun1(void *arg){    //線程1先申請資源1,再申請資源2    //加鎖    pthread_mutex_lock(&mutex1);    printf("線程1加鎖資源1ok....\n");    pthread_mutex_lock(&mutex2);    printf("線程1加鎖資源2ok....\n");    printf("線程1執行臨界代碼");    //解鎖    pthread_mutex_unlock(&mutex1);    pthread_mutex_unlock(&mutex2);    return NULL;  }//線程2處理函數void *fun2(void* arg){    //線程2先申請資源2,再申請資源1    //加鎖    pthread_mutex_lock(&mutex2);    printf("線程2加鎖資源1ok....\n");    pthread_mutex_lock(&mutex1);    printf("線程2加鎖資源2ok....\n");    printf("線程2執行臨界區代碼....\n");    //解鎖    pthread_mutex_unlock(&mutex2);    pthread_mutex_unlock(&mutex1);    return NULL;}//演示死鎖int main(){    int ret = -1;    int ret1 = -1;    pthread_t tid1,tid2;    //初始化互斥量    pthread_mutex_init(&mutex1,NULL);    pthread_mutex_init(&mutex2,NULL);    //創建兩個線程    pthread_create(&tid1,NULL,fun1,NULL);    pthread_create(&tid2,NULL,fun2,NULL);    //回收資源    ret = pthread_join(tid1,NULL);    ret = pthread_join(tid2,NULL);    if(0!=ret)    {      printf("線程1資源回收失敗\n");      return 1;    }    if(0!=ret1)    {      printf("線程2資源回收失敗\n");      return 1;    }    //銷毀互斥鎖    pthread_mutex_destroy(&mutex1);    pthread_mutex_destroy(&mutex2);    return 0;}運行結果如下:
二 Linux--多線程

文章插圖

推薦閱讀