N-1-萘乙基二胺盐酸盐 2022-09-24 17:58 采纳率: 100%
浏览 102
已结题

哲学家进餐问题 条件变量

用c语言、条件变量解决哲学家进餐问题。我的解决思路:以左叉子和右叉子是否同时存在作为条件来判断哲学家是否可以吃饭。
1.把五把叉子的状态初始化为TRUE(存在)。cond数组保存的是五个哲学家的条件变量。
2.testfork函数中(forkstatus[left]==TRUE&&forkstatus[right]==TRUE)是哲学家是否可以吃饭的条件,不满足条件就进入等待;满足条件就改变叉子的状态(forkstatus[left]=FALSE;forkstatus[right]=FALSE;//拿起左叉子和右叉子)。
3.eating函数就不解释了。
4.returnforks函数表示放下叉子。放下叉子后并唤醒他的相邻哲学家。

存在的问题:运行后发现每次只有两个哲学家参与吃饭。
请指出我的问题。
代码如下:

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>
#include <assert.h>
#include <sys/types.h>

#define NUM 5

pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;

pthread_cond_t cond[NUM]={
                                    PTHREAD_COND_INITIALIZER,PTHREAD_COND_INITIALIZER,
                                    PTHREAD_COND_INITIALIZER,PTHREAD_COND_INITIALIZER,
                                    PTHREAD_COND_INITIALIZER
                                    };

#define FALSE -1
#define TRUE 1

volatile int forkstatus[5]={TRUE,TRUE,TRUE,TRUE,TRUE};

void test_forks(int id)
{
    int left=id%NUM;//左叉子的编号
    int right=(id+1)%NUM;//右叉子的编号

    pthread_mutex_lock(&mutex);
    while(!(forkstatus[left]==TRUE&&forkstatus[right]==TRUE))//条件是左叉子和右叉子同时存在
    {
        pthread_cond_wait(&cond[id],&mutex);
    }
    assert(forkstatus[left]==TRUE&&forkstatus[right]==TRUE);
    forkstatus[left]=FALSE;
    forkstatus[right]=FALSE;//拿起左叉子和右叉子
    assert(forkstatus[left]==FALSE&&forkstatus[right]==FALSE);
    pthread_mutex_unlock(&mutex);
}

void returnforks(int id)
{
    int left=id%NUM;//左叉子的编号
    int right=(id+1)%NUM;//右叉子的编号

    int l=(id-1+NUM)%NUM;//左哲学家id
    int r=(id+1)%NUM;//右哲学家id

    pthread_mutex_lock(&mutex);//在互斥锁的保护下把叉子放好
    forkstatus[left]=TRUE;
    forkstatus[right]=TRUE;

    pthread_cond_signal(&cond[l]);
    pthread_cond_signal(&cond[r]);
    pthread_mutex_unlock(&mutex);
}

void eating(int id)
{
    printf("哲学家%d正在吃饭\n",id);
    sleep(id);
    printf("哲学家%d吃完饭了\n",id);
}

void *philosopher(void *i)
{
    int id=*((int *)i);//哲学家id
    while(1)
    {
        test_forks(id);
        eating(id);
        returnforks(id);
    }
}

int main(int argc,char** argv)
{
    int i;
    pthread_t tid[NUM];
    for(i=0;i<NUM;i++)
    {
        pthread_create(&tid[i],NULL,philosopher,&i);
    }
    getchar();
    return 0;
}


  • 写回答

1条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2022-09-24 19:00
    关注
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 9月24日
  • 已采纳回答 9月24日
  • 创建了问题 9月24日

悬赏问题

  • ¥15 为什么我运行这个网络会出现以下报错?CRNN神经网络
  • ¥20 steam下载游戏占用内存
  • ¥15 CST保存项目时失败
  • ¥15 树莓派5怎么用camera module 3啊
  • ¥20 java在应用程序里获取不到扬声器设备
  • ¥15 echarts动画效果的问题,请帮我添加一个动画。不要机器人回答。
  • ¥15 Attention is all you need 的代码运行
  • ¥15 一个服务器已经有一个系统了如果用usb再装一个系统,原来的系统会被覆盖掉吗
  • ¥15 使用esm_msa1_t12_100M_UR50S蛋白质语言模型进行零样本预测时,终端显示出了sequence handled的进度条,但是并不出结果就自动终止回到命令提示行了是怎么回事:
  • ¥15 前置放大电路与功率放大电路相连放大倍数出现问题