您的位置:首页 > 运维架构 > Linux

经典同步问题linux下的C实现:生产者-消费者问题,读者-写者问题,哲学家问题

2013-04-11 22:36 661 查看
1.生产者-消费者问题

/*===============================================================

 * File Name : producerConsumerProblem.c
 * Creation Date : 2013-04-11
 * Last Modified : 2013年04月11日 星期四 20时53分13秒
 * Purpose :test linux semaphore usage

================================================================*/
#include <stdio.h>
#include <sys/types.h>
#include <semaphore.h>
#include <pthread.h>
#include <stdlib.h>

void *producer_handler(void *ptr);
void *consumer_handler(void *ptr);

sem_t mutex,blank,fill;
int *buffer;
int in=0,out=0,buffer_size=10;

void main()
{
	if((buffer=(int *)malloc(buffer_size*sizeof(int)))==NULL)
		printf("can't allocate memroy on heap\n");
	sem_init(&mutex,0,1);
	sem_init(&blank,0,buffer_size);
	sem_init(&fill,0,0);

	int err;
	pthread_t producer,consumer;
	err=pthread_create(&producer,NULL,producer_handler,NULL);
	if(err!=0)
		err_quit("can't create thread: %s\n",strerror(err));
	err=pthread_create(&consumer,NULL,consumer_handler,NULL);
	if(err!=0)
		err_quit("can't create thread: %s\n",strerror(err));

	sleep(10);

}

void *producer_handler(void *ptr)
{
	while(1){
		static int data=0;
		sem_wait(&blank);
	//	sem_wait(&mutex);
	
		buffer[in]=++data;
		printf("%d has been input to the buffer\n",data);
		in=(in+1+buffer_size)%buffer_size;
	//	sem_post(&mutex);
		sem_post(&fill);
		sleep(1);
	}
	return ((void *)0);
}

void *consumer_handler(void *ptr)
{
	while(1){
		int fetch;
		sem_wait(&fill);
	//	sem_wait(&mutex);
		fetch=buffer[out];
		out=(out+1+buffer_size)%buffer_size;
		printf("%d has been fetched\n",fetch);
	//	sem_post(&mutex);
		sem_post(&blank);
		sleep(2);
	}
	return ((void *)0);
}


2.读者-写者问题

/*===============================================================

 * File Name : readerWriterProblem.c
 * Creation Date : 2013-04-11
 * Last Modified : 2013年04月11日 星期四 22时42分45秒
 * Purpose :

================================================================*/

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

#define READER_NUM 5
void *reader_handler(void *ptr);
void *writer_handler(void *ptr);

sem_t write_mutex;
sem_t mutex;
int read_count;

void main()
{
	sem_init(&write_mutex,0,1);
	sem_init(&mutex,0,1);
	read_count=0;
	
	int err,i;
	pthread_t reader[READER_NUM],writer;
	int args[READER_NUM];
	for(i=0;i<READER_NUM;++i){
		args[i]=i;
		err=pthread_create(&reader[i],NULL,reader_handler,(void*)&args[i]);
		if(err!=0)
			err_quit("can't create thread: %s\n",strerror(err));
	}
	err=pthread_create(&writer,NULL,writer_handler,NULL);
	if(err!=0)
		err_quit("can't create thread: %s\n",strerror(err));

	sleep(10);

}

void *reader_handler(void *ptr)
{
	while(1){
		if(read_count==0){
			sem_wait(&write_mutex);
		}
		sem_wait(&mutex);
		++read_count;
		sem_post(&mutex);

		printf("There are %d readers reading\n",read_count);
		sleep(1);

		sem_wait(&mutex);
		--read_count;
		sem_post(&mutex);

		if(read_count==0){
			sem_post(&write_mutex);
		}
		sleep(1);
	}
	return ((void *)0);
}

void *writer_handler(void *ptr)
{
	while(1){
		if(read_count==0){
			sem_wait(&write_mutex);
			printf("Writer writes\n");
			sem_post(&write_mutex);
		}
		else
			printf("Writer failed\n");
		sleep(1);
	}
	return ((void *)0);
}


3.哲学家进餐问题

有一点要注意:

就是循环生生成线程时,要给线程处理函数传入计数器参数时,不能直接用计数器的地址——因为计数器会现在主函数中改变。显然也不能用循环中的临时变量来记录。所以只好再有外部数组来记录这些实参值了。

/*===============================================================

 * File Name : dinningPhilosophersProblem.c
 * Creation Date : 2013-04-11
 * Last Modified : 2013年04月11日 星期四 21时34分18秒
 * Purpose :

================================================================*/

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

#define PHILO_NUM 5
void *philosopher(void *arg);

sem_t sema[PHILO_NUM];
sem_t mutex;
void main()
{
	int i,err;
	int args[PHILO_NUM];
	for(i=0;i<PHILO_NUM;++i){
		sem_init(sema+i,0,1);
		args[i]=i;
	}  
	sem_init(&mutex,0,1);
	pthread_t philosophers[PHILO_NUM];
	for(i=0;i<PHILO_NUM;++i){
		err=pthread_create(philosophers+i,NULL,philosopher,(void*)&args[i]);
		if(err!=0)
			err_quit("can't create thread: %s\n",strerror(err));
	}
	sleep(5);
}

void *philosopher(void *arg)
{
	int num;
	num=*((int *)arg);
	//printf("Philosopher %d eats\n",num);
	while(1){
		sem_wait(&mutex); 
		sem_wait(&sema[num]);
		sem_wait(&sema[(num+1)%PHILO_NUM]);
		sem_post(&mutex);
		printf("Philosopher %d eats\n",num);
		sem_post(&sema[num]);
		sem_post(&(sema[(num+1)%PHILO_NUM]));
		sleep(1);
	}

	return ((void *)0);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐