日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

哲学家就餐问题--信号量和互斥量预防死锁

發布時間:2025/6/17 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 哲学家就餐问题--信号量和互斥量预防死锁 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

哲學家就餐問題可以采取預防死鎖的方案,就是使用互斥量和信號量鎖定資源。

互斥量:

對資源進行鎖定的意思就是說,當一個哲學家使用叉子的時候,他首先要先把叉子鎖定,然后,拿起來。這個時候如果別的哲學家也來拿相同的叉子,發現,該叉子是被互斥量鎖定了,不能夠拿,那么,他就不會來搶占這個叉子,而是在排等待隊列中。這樣就可以避免死鎖的發生。

信號量:

同樣,沒有資源的時候,信號量的值是0,有的時候就不斷地加1。“0,1”信號和互斥量是相似的。

使用互斥量預防死鎖代碼:

/***哲學家吃飯問題:幾個哲學家吃飯,假定哲學家有五個人,這五個哲學家坐在一張圓桌上面,*每個哲學家的左手旁邊都放有一個叉子(fork),那么,這圍城一圈的五個哲學家有五個叉子*。每個哲學家有三種狀態,thinking(思考),trying(嘗試去拿叉子吃飯),eating(已*經拿起叉子,正在吃飯)。每次吃飯需要兩個叉子,也就是哲學家左右手邊的叉子。* *//*** 本例使用pthread庫實現哲學家進餐的問題。* *//***在這個例子中使用互斥量解決死鎖問題。 * */#include <stdio.h> #include <pthread.h> #include <stdlib.h> #include <sys/wait.h>//為了使用sleep()函數 #include <unistd.h>//參數的識別 #include <getopt.h> //長命令的解析//哲學家的數目 int Number;//聲明共享變量fork,其中fork的數目和哲學家數目是相同的 pthread_mutex_t *pfork;//定義一個philosopher的三個狀態 #define Thinking 1 #define Trying 2 #define Eating 3int *state;void *EatMeal();//得到參數 void GetArg(char* argv[] /*in*/,int* number /*out*/); void main(int argc, char* argv[]) {int k =0;while(k<1){int option_index = 0;int rvalue = 0;struct option long_option[] = {{"normal",0,0,0 },{"method1",0,0,0},{"method2",0,0,0}};rvalue = getopt_long_only(argc,argv, "a:bc::", long_option,&option_index);switch(option_index){case 0 : printf("%s\n",long_option[option_index].name);break;case 1 : printf("%s\n",long_option[option_index].name);break;case 2 : printf("%s\n",long_option[option_index].name);break;}k++;}GetArg(argv, &Number);pfork = malloc(Number*sizeof(pthread_mutex_t));state = malloc(Number*sizeof(int));//聲明進程數組,每一個進程代表一個哲學家 pthread_t philosopher[Number];int i;//初始化每一個資源實例for( i = 0; i < Number; i++){pthread_mutex_init(&pfork[i],NULL);}//創建和哲學家數量想對應的進程,并且每個進程開始進行吃飯的活動for( i = 0; i < Number; i++){//記錄當前進程的編號,并傳遞到Meal()函數中int j = i;pthread_create(&philosopher[i], NULL, EatMeal, &j);printf("I am philosopher %d\n", j);}//將所有的進程進行Join操作。for( i=0; i < Number; i++){pthread_join(philosopher[i], NULL);}//退出程序pthread_exit(0);return ;}void *EatMeal(int *i) {//記錄當前的線程id號int id = *i;state[id] = Thinking; //線程初始化的時候為Thinkingint leftFork = (id + Number -1) % Number;int rightFork = (id + Number +1) % Number;int mealTime = 5;int mymealTime = 0;while (mymealTime < mealTime) //每個philosopher必須吃得符合規定 {if(state[id] == Thinking){printf("Philosopher %d is thinking\n", id);sleep(1);state[id] = Trying;}else if(state[id] == Trying){printf("Philosopher %d is Trying\n", id);sleep(1);pthread_mutex_lock(&pfork[leftFork]);pthread_mutex_lock(&pfork[rightFork]);state[id] = Eating;}else {printf("Philosopher %d is Eating\n", id);sleep(1);mymealTime++;pthread_mutex_unlock(&pfork[leftFork]);pthread_mutex_unlock(&pfork[rightFork]);}}}void GetArg(char * argv[],int* number) {*number = strtol(argv[1], NULL, 10); } View Code

使用信號量預防死鎖代碼:

/***哲學家吃飯問題:幾個哲學家吃飯,假定哲學家有五個人,這五個哲學家坐在一張圓桌上面,*每個哲學家的左手旁邊都放有一個叉子(fork),那么,這圍城一圈的五個哲學家有五個叉子*。每個哲學家有三種狀態,thinking(思考),trying(嘗試去拿叉子吃飯),eating(已*經拿起叉子,正在吃飯)。每次吃飯需要兩個叉子,也就是哲學家左右手邊的叉子。* *//*** 本例使用信號量解決哲學家進餐的問題。* 哲學家的數目和叉子的數目相等。* 叉子是幾個哲學家共享的資源,將這些資源聲明為信號量,其中每一個資源為一個信號量,* 本例中的信號量為0和1兩個值,當信號量為0的時候,是不能夠被另外一個進程使用,當* 信號兩為1的時候,可以被使用。* */ #include <stdio.h> #include <pthread.h> #include <math.h> #include <sys/time.h> #include <semaphore.h> #include <stdlib.h> //設定哲學家的數目 int Number;//定義哲學家的三種狀態 #define Thinking 1 #define Trying 2 #define Eating 3pthread_mutex_t mutex; //聲明一個互斥量,用來在使用資源的時候鎖住 sem_t *semph; //為每一個叉子定義信號量int *state; //記錄每一個哲學家的狀態//得到參數 void GetArg(char* argv[];int* number; );void main(int argc, char* argv[]) {GetArg(argv, &Number);semph = malloc(Number* sizeof(sem_t));state = malloc(Number* sizeof(int));pthread_t philosopher[Number]; //為每一個哲學家聲明一個進程 pthread_mutex_init(&mutex, NULL); //初始化互斥量void * EatMeal(); //哲學家操作的主要函數int i =0;for(i = 0; i < Number; i++){int j = i;sem_init(&semph[i], 0, 1);// 初始化信號量,信號量的值為0或者1//創建進程,每個進程執行函數EatMeal()中的操作int res = pthread_create(&philosopher[i], NULL, EatMeal, &j); printf("This is thread %d \n",i);/*//檢查是否創建進程成功if(res !=0){printf("%d sucess!\n", i);}*/}for(i = 0; i < Number; i++){pthread_join(philosopher[i], NULL);}pthread_exit(0);//sleep(100);//主要進程執行等待的任務(應該修改,直到每一個線程都被完成主進程才結束) }//定義哲學家吃飯的這個問題 void *EatMeal(int *j) {int phiD = *j; //記錄哲學家的id號int leftPhi; //記錄哲學家左邊的叉子的id號int rightPhi; //記錄哲學家右邊的叉子的id號 leftPhi = (phiD + Number - 1) % Number;rightPhi = (phiD + Number + 1) % Number;state[phiD] = Thinking; //哲學家的初始狀態設為 Thinkingint mymealCount = 0;int mealCount = 1;double time;while(mymealCount < mealCount) //規定每個人吃飯不能超過最大吃飯次數 {time = (rand()%9 + 1)/100.0; //得到的時間在0.01 - 0.1之間//如果當前的狀態是Thinking,那么則轉化為Trying的狀態int i = state[phiD];//記錄當前的狀態if(state[phiD] == Thinking){printf("%d philosopher is thinking!\n", phiD);sleep(1);//在這個狀態停留一段時間state[phiD] = Trying;}//如果當前的狀態是Trying,則檢查是否能夠達到Eating的狀態else if(state[phiD] == Trying){printf("%d philosopher is trying!\n",phiD);sleep(1);//在這個狀態停留一段時間if(!sem_wait(&semph[leftPhi]))//如果能夠拿起哲學家左邊的叉子 {if(!sem_wait(&semph[rightPhi]))//也能夠拿起右邊的叉子 {state[phiD] = Eating;}else//不能拿起右邊的叉子 {sem_post(&semph[leftPhi]);//放下左邊的叉子 }}}else //狀態為 Eating {printf("%d philosopher is eating!\n",phiD);sleep(1);//先吃一段時間sem_post(&semph[leftPhi]);//放下左邊的叉子sem_post(&semph[rightPhi]);//放下右邊的叉子state[phiD] = Thinking;mymealCount++;}if(i != state[phiD]){pthread_mutex_lock(&mutex);printf("%d state tranformed from %d to %d\n", phiD, i, state[phiD]);pthread_mutex_unlock(&mutex);}} }void GetArg(char* argv[],int* number) {*number = strtol(argv[1], NULL, 10); } View Code

?

轉載于:https://www.cnblogs.com/SevenwindMa/p/3485129.html

總結

以上是生活随笔為你收集整理的哲学家就餐问题--信号量和互斥量预防死锁的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。