📄 philosopher.c
字号:
#include <stdio.h>
#include <unistd.h>
#include <limits.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <sys/sem.h>#include <sys/shm.h>#include <time.h>#define N 5 //哲学家个数
#define LEFT (i+N-1)%N //i左边的哲学家
#define RIGHT (i+1)%N //i右边的哲学家
#define THINKING 0
#define HUNGRY 1
#define EATING 2
//共享内存的结构typedef struct{ int state[N];//哲学家的状态 int count;//就餐哲学家的个数} shared_sum;
static int semid;//标记信号量集static shared_sum *sharedsum;//实现共享内存的指针
//创建编号为0~N的N+1个信号量,第N个信号量为MUTEX信号量
void create()
{
int semnum;
if((semid = semget(IPC_PRIVATE,N+1,0666))==-1)//创建信号量集
perror("failed to create semaphore");
for(semnum=0;semnum<=N;semnum++)
{
if(semctl(semid,semnum,SETVAL,1)==-1)//初始化各信号量
perror("failed to set semaphore");
}
}//开辟共享内存区,存储哲学家状态int shmem(){ int shid; int num; shid = shmget(IPC_PRIVATE,sizeof(shared_sum),IPC_CREAT|0666);//开辟内存区 if(shid ==-1) { if(((shid = shmget(IPC_PRIVATE,sizeof(shared_sum),IPC_CREAT|0664))==-1)|| ((sharedsum = (shared_sum *)shmat(shid,NULL,0)) == (void *)-1)) { return -1; } } else { sharedsum = (shared_sum *)shmat(shid,NULL,0);//内存区数据关联 if(sharedsum ==(void *)-1) return -1;
//共享内存初始化 for(num=0;num<N;num++) sharedsum->state[num] = 0; sharedsum->count = 0; } return 0; }
//某个信号量的up操作void up(int num)
{
struct sembuf v_buf = {num,1,SEM_UNDO};
semop(semid,&v_buf,1);
}
//某个信号量的down操作
void down(int num)
{
struct sembuf p_buf = {num,-1,SEM_UNDO};
semop(semid,&p_buf,1);
}
//检查是否可吃void test(int i){ int count; int j; if(sharedsum->state[i] == HUNGRY && sharedsum->state[LEFT]!=EATING && sharedsum->state[RIGHT]!=EATING) { sharedsum->state[i] = EATING; up(i); printf("philosopher "); for(j=0;j<N;j++)//输出某一时刻处于吃状态的哲学家 { if(sharedsum->state[j] == EATING) printf("%d ",j); } printf("now are eating\n"); }}
//拿起叉子void take_forks(int i){ down(N);//进入临界区 sharedsum->state[i] = HUNGRY; test(i);//尝试获取两把叉子 up(N);//离开临界区 down(i);//如果得不到需要的叉子则阻塞 }
//放下叉子void put_forks(int i){ down(N);//进入临界区 sharedsum->state[i] = THINKING; test(LEFT);//检查左边的哲学家现在可以吃吗 test(RIGHT);//检查右边的哲学家现在可以吃吗 up(N);//离开临界区}//代表一个哲学家void philosopher(int i){
int j; time_t t; srand((unsigned) time(&t));//初始化随机数发生器 for(j=0;j<10;j++) { printf("philosopher %d is thinking\n",i); take_forks(i); //要求得到两把叉子或被阻塞 usleep(rand() % 100);//随机睡眠0~100毫秒 put_forks(i);//把两把叉子入回桌子 }}
int main()
{ pid_t pid[5]; int i; create(); if(shmem()==-1) { return -1; }
for(i=0;i<5;i++)//创建5个哲学家
{
pid[i]=fork(); if(pid[i] == 0) {
philosopher(i);//运行哲学家函数 return 0; } } for(i=0;i<5;i++) wait();//等待子进程结束
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -