哲学家就餐问题——奇数号哲学家先拿起他左手的筷子,然后再拿起他右手的筷子,而偶数号哲学家则先拿起他右手的筷子,然后再拿起他左手的筷子

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
#include <errno.h>


#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/wait.h>
union semun
{
int val;
struct semid_ds *buf;
unsigned short *array;
struct seminfo *__buf;
};


#define ERR_EXIT(m) \
do { \
perror(m); \
exit(EXIT_FAILURE); \
} while(0)


//wait操作
void wait_l(int semid,int num)
{
struct sembuf sb={num,-1,0};
semop(num,&sb,1);//第三个参数,信号操作的数量恒大于等于1
}
//signal操作


void signal_l(int semid,int num)
{
struct sembuf sb={num,-1,0};//第三个参数,信号操作的数量恒大于等于1
semop(num,&sb,1);
}


#define DELAY (rand() % 5 + 1)
//科学家要做的事
void ph(int semid,int num)
{
for(;;)//死循环
{
//判断哲学家的编号是奇数还是偶数
//奇数先申请左边的筷子,偶数先申请右边的筷子
if(num%2!=0)
{//判断奇数
printf("%d is thinking\n",num);
sleep(DELAY);
printf("%d is hungry\n",num);
sleep(DELAY);
//wait操作
wait_l(semid,num);
wait_l(semid,(num+1)%5);
//wait_rightcs(semid,(num+1)%5);
printf("%d is eating\n",num);
sleep(DELAY);
//signal操作
//signal_rightcs(semid,(num+1)%5);
signal_l(semid,num);
signal_l(semid,(num+1)%5);
}
if(num%2==0)
{//判断偶数
printf("%d is thinking\n",num);
sleep(DELAY);
printf("%d is hungry\n",num);
sleep(DELAY);
//wait
//wait_rightcs(semid,(num+1)%5);
wait_l(semid,(num+1)%5);
wait_l(semid,num);
//signal
signal_l(semid,num);
signal_l(semid,(num+1)%5);
//signal_rightcs(semid,(num+1)%5);
}
}
}
int main(int argc,char *argv[])
{
int semid;
//创建5个信号量
semid=semget(IPC_PRIVATE,5,IPC_CREAT | 0666);
union semun su;
su.val=1;
int i;
for(i=0;i<5;i++)
{
//注意第二个参数也是索引
semctl(semid,i,SETVAL,su);
}
//创建4个子进程
pid_t pid;
int num=5;
for(i=0;i<4;i++)
{
pid=fork();
if(pid<0) { ERR_EXIT("fork");}
if(pid==0) { num=i;break;}
}
//哲学家要做的事
ph(semid,num);
return 0;
}












































  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值