哲学家吃饭问题 代码实现如何 避免线程死锁

来源:互联网 发布:网络共享文件夹打不开 编辑:程序博客网 时间:2024/04/27 17:49

问题描述:
    假设有5个哲学家,他们花费一生中的时光思考和吃饭。这些哲学家共用一个圆桌,每个哲学家都有一把椅子。在桌子中央是一碗通心面,在桌子上放着5只筷子。当一个哲学家思考时,他与其他同事不交互。时而,哲学家会感到饥饿,并试图拿起与他相近的两只筷子(他与邻近左、右之间的筷子)。一只筷子一次只能被一个哲学家拿起。显然,他不能从其他哲学家手里拿走筷子。当一个饥饿的哲学家同时有两只筷子时,他就可以吃饭。当吃完后,他会放下两只筷子,并再次开始思考。

代码实现:

#include <stdio.h>#include <errno.h>#include <unistd.h>#include <sys/types.h>#include <string.h>#include <stdlib.h>#include <fcntl.h>#include <sys/stat.h>#include <time.h>#include <pthread.h>/** 线程的处理函数,会有死锁 */void* ReadyEatDeadLock(void* arg);/** 线程的处理函数,不会有死锁 */void* ReadyEat(void* arg);/** 线程锁 ,定义6把锁*/pthread_mutex_t mutix[6] ;/** 线程的处理函数,不会有死锁 */void* ReadyEat(void* arg){    int nLeft = 0,nRight = 0;    int nArg = (int)arg;    //printf("%d\n",nArg);    switch (nArg)    {        case 1:         {            nLeft = 5;            nRight = 1;            break;        }        case 2:         {            nLeft = 1;            nRight = 2;            break;        }        case 3:         {            nLeft = 2;            nRight = 3;            break;        }        case 4:         {            nLeft = 3;            nRight = 4;            break;        }        case 5:         {            nLeft = 4;            nRight = 5;            break;        }        default:        {            printf("The parameter is wrong\n");            break;        }    }    while(1)    {        /** 思考一秒钟 */        sleep(1);        /** 拿起左边的筷子,如果正被锁住则阻塞 */        pthread_mutex_lock(&mutix[nLeft]);        /** 如果右手边的筷子被上锁 */        if(EBUSY == pthread_mutex_trylock(&mutix[nRight]))        {            /** 放下左手上的筷子 */            pthread_mutex_unlock(&mutix[nLeft]);            continue;        }        printf("The %d man is eating  1 秒钟\n",nArg);        sleep(1);        /** 放下左手上的筷子 */        pthread_mutex_unlock(&mutix[nLeft]);        /** 放下右手上的筷子 */        pthread_mutex_unlock(&mutix[nRight]);    }}int main(){    pthread_t tid[6];    int nIndex = 0;    int nRet = 0;    char szPthreadFun[10] = {"ReadyEat"};    /** 初始化线程锁 */    for(nIndex = 1; nIndex < 6; nIndex++)    {        pthread_mutex_init(&mutix[nIndex],NULL);    }    /** 创建5个线程*/    for(nIndex = 1; nIndex < 6; nIndex++)    {        nRet = pthread_create(&tid[nIndex],NULL,ReadyEatDeadLock,(void*)nIndex);        if(0 != nRet)        {            printf("create %d pthread failed\n",nIndex);            return -1;        }    }    while(1)    {        /** 进程不退出,确保线程正在运行 */    }    return 0;}/** 线程的处理函数,会有死锁 */void* ReadyEatDeadLock(void* arg){    int nLeft = 0,nRight = 0;    int nArg = (int)arg;    //printf("%d\n",nArg);    switch (nArg)    {        case 1:         {            nLeft = 5;            nRight = 1;            break;        }        case 2:         {            nLeft = 1;            nRight = 2;            break;        }        case 3:         {            nLeft = 2;            nRight = 3;            break;        }        case 4:         {            nLeft = 3;            nRight = 4;            break;        }        case 5:         {            nLeft = 4;            nRight = 5;            break;        }        default:        {            printf("The parameter is wrong\n");            break;        }    }    while(1)    {        /** 思考一秒钟 */        usleep(1);        /** 拿起左边的筷子,如果正被锁住则阻塞 */        pthread_mutex_lock(&mutix[nLeft]);        /** 拿起右边的筷子,如果正被锁住则阻塞 */        pthread_mutex_lock(&mutix[nRight]);        printf("The %d man is eating  1 秒钟\n",nArg);        usleep(1);        /** 放下左手上的筷子 */        pthread_mutex_unlock(&mutix[nLeft]);        /** 放下右手上的筷子 */        pthread_mutex_unlock(&mutix[nRight]);    }}
0 0
原创粉丝点击