哲学家吃饭

进程间信号量

#include<stdio.h>
#include<stdlib.h>
#include<semaphore.h>
#include<unistd.h>
#include<sys/wait.h>
#include<sys/types.h>
#include<errno.h>
#include<sys/mman.h>

//sem_t用于进程间通信需要放到共享内存区
void *createSM(size_t size)//创建共享区
{
	void *addr=mmap(NULL,size,PROT_READ|PROT_WRITE,MAP_ANON|MAP_SHARED,-1,0);
	if(addr==MAP_FAILED)
		return NULL;
	return addr;
}

void *freeSM(void* addr,size_t size)//释放共享区
{
	if(munmap(addr,size)==-1)
		printf("munmap(%p,%d) failed",addr,(int)size);
}

sem_t* forks[5];//五根筷子
sem_t* four;//拿叉子的资格,最多四人有资格

int main()
{
	int i,times=2;
	//创建共享区
	for(i=0;i<5;i++)
	{
		forks[i]=createSM(sizeof(sem_t));
		if(forks[i]==NULL)
		{
			printf("create shared memory failed\n");
			exit(1);
		}
	}
	four=createSM(sizeof(sem_t));
	if(four==NULL)
	{
		printf("create shared memory failed\n");
		exit(1);
	}

	//初始化信号量
	for(i=0;i<5;i++)
	{
		int ret=sem_init(forks[i],1,1);
		if(ret==-1)
		{
			fprintf(stderr,"%s\n",strerror(errno));
			exit(-1);
		}
	}
	int ret=sem_init(four,1,4);
	if(ret==-1)
	{
		fprintf(stderr,"%s\n",strerror(errno));
		exit(-1);
	}

	//创建五个进程
	for(i=0;i<5;i++)
	{
		pid_t pid=fork();
		if(pid==-1)
		{
			perror("fork");
			exit(1);
		}
		else if(pid==0)
				break;
	}

	//父进程
	if(i==5)
	{
		int n=5;
		while(n)
		{
			pid_t pid=waitpid(-1,NULL,WNOHANG);
			if(pid>0)
			{
				n--;
				printf("子进%d程已被回收\n",pid);
			}
		}
		sleep(1);
	}

	//子进程
	if(i<5)
	{
		while(times--)
		{
			printf("哲学家%d思考1秒...\n",i);
			sleep(1);

			//阻塞等待获得资格
			sem_wait(four);
			sem_wait(forks[i]);
			sem_wait(forks[(i+1)%5]);//获得两根筷子

			printf("哲学家%d开始吃饭...\n",i);
			sleep(1);
			printf("哲学家%d吃完了,开始释放资源...\n",i);


			sem_post(forks[i]);
			sem_post(forks[(i+1)%5]);
			sem_post(four);

			sleep(1);
		}
	}

	//释放资源
	for(i=0;i<5;i++)
	{
		freeSM(forks[i],sizeof(sem_t));
		sem_destroy(forks[i]);
	}
	freeSM(four,sizeof(sem_t));
	sem_destroy(forks[i]);

	return 0;
}


进程间互斥量

#include<stdio.h>
#include<stdlib.h>
#include<semaphore.h>
#include<unistd.h>
#include<sys/wait.h>
#include<sys/types.h>
#include<errno.h>
#include<sys/mman.h>
#include<pthread.h>

typedef struct
{
	pthread_mutex_t mutex;
	pthread_mutexattr_t mutexattr;
} mt;

int main()
{
	int i;
	mt* forks[5];
	pid_t pid;

	//创建匿名映射区
	for(i=0;i<5;i++)
	{
		forks[i]=mmap(NULL,sizeof(mt),PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANON,-1,0);
		//memset(forks[i],0,sizeof(mt));
		//初始化mutexattr
		pthread_mutexattr_init(&forks[i]->mutexattr);
		//修改属性为进程间共享
		pthread_mutexattr_setpshared(&forks[i]->mutexattr,PTHREAD_PROCESS_SHARED);
		//初始化锁
		pthread_mutex_init(&forks[i]->mutex,&forks[i]->mutexattr);
	}

	//创建并初始化信号量
	sem_t* four;
	four=mmap(NULL,sizeof(sem_t),PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANON,-1,0);
	sem_init(four,1,4);

	//创建5个子进程
	for(i=0;i<5;i++)
	{
		pid_t pid=fork();
		if(pid==0)
			break;
	}

	if(i==5)//父进程
	{
		int n=5;
		while(n)
		{
			pid_t pid=waitpid(-1,NULL,WNOHANG);
			if(pid>0)
			{
				n--;
				printf("子进程%d已被回收\n",pid);
			}
		}
	}

	if(i<5)
	{
		int times=2;
		while(times--)
		{
			printf("哲学家%d思考1秒...\n",i);
			sleep(1);
			
			//申请资源
			sem_wait(four);
			pthread_mutex_lock(&forks[i]->mutex);
			pthread_mutex_lock(&forks[(i+1)%5]->mutex);
			
			printf("哲学家%d开始吃饭...\n",i);
			sleep(1);
            //释放资源
			pthread_mutex_unlock(&forks[i]->mutex);
			pthread_mutex_unlock(&forks[(i+1)%5]->mutex);
			sem_post(four);

			printf("哲学家%d吃完了...\n",i);
		}
	}

	for(i=0;i<5;i++)
	{
		pthread_mutexattr_destroy(&forks[i]->mutexattr);//销毁mutexattr
		pthread_mutex_destroy(&forks[i]->mutex);//销毁mutex
		munmap(forks[i],sizeof(mt));
	}

	sem_destroy(four);
	munmap(four,sizeof(sem_t));

	printf("哲学家们已经吃完饭...\n");

	return 0;
}



线程间信号量

#include<stdio.h>
#include<stdlib.h>
#include<semaphore.h>
#include<unistd.h>
#include<sys/wait.h>
#include<sys/types.h>
#include<errno.h>
#include<sys/mman.h>
#include<pthread.h>

sem_t forks[5],four;

void* eat(void* arg)
{
	int i=(int)arg;
	//printf("i=%d\n",i);
	int times=2;
	while(times--)
	{
		printf("哲学家%d开始思考1秒...\n",i);

		sem_wait(&four);
		sem_wait(&forks[i]);
		sem_wait(&forks[(i+1)%5]);

		printf("哲学家%d开始吃饭...\n",i);
		sleep(1);

		sem_post(&forks[i]);
		sem_post(&forks[(i+1)%5]);
		sem_post(&four);

		printf("哲学家%d吃完了...\n",i);
		sleep(1);
	}

}

int main()
{
	//初始化信号量
	int i;
	for(i=0;i<5;i++)
		sem_init(&forks[i],0,1);
	sem_init(&four,0,4);

	//创建子线程
	pthread_t pid[5];
	for(i=0;i<5;i++)
		pthread_create(&pid[i],NULL,eat,(void*)i);

	//回收子线程
	for(i=0;i<5;i++)
	{
		pthread_join(pid[i],NULL);
		printf("------------子线程%d已被回收\n",i);
	}

	//销毁信号量
	sem_destroy(&four);
	for(i=0;i<5;i++)
		sem_destroy(&forks[i]);

	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值