⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 philosopher.c

📁 操作系统课程设计
💻 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 + -