经典同步问题linux下的C实现:生产者-消费者问题,读者-写者问题,哲学家问题
来源:互联网 发布:mac air能玩什么游戏 编辑:程序博客网 时间:2024/04/30 18:29
http://blog.csdn.net/life_hunter/article/details/8790553
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);
- }
哲学家问题解决:
comments:5个人5副刀叉。4个人吃饭毕竟不向5个人,肯定至少有一个会吃到,然后放下,然后其他的人就不会一直hold,所以让其中之一先sleep一下。即不会死锁。
但是从理论上讲,只是开始的时候,4人同吃,不会出现死锁。
但是过了id=0,sleep之后,又变成5个人同吃。还是可能存在死锁的可能。
#include <pthread.h> #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <errno.h> #include <assert.h> #define PHILOS 5 #define DELAY 5000 #define FOOD 50 void *philosopher (void *id); void grab_chopstick(int , int , char *); void down_chopsticks (int , int); int food_on_table(); pthread_mutex_t chopstick[PHILOS]; pthread_t philo[PHILOS]; pthread_mutex_t food_lock; int sleep_seconds=10; int main (int argn,char **argv) { int i; if (argn==2) sleep_seconds=atoi(argv[1]); pthread_mutex_init(&food_lock,NULL); for (i=0;i<PHILOS;i++) pthread_mutex_init(&chopstick[i],NULL); for (i=0;i<PHILOS;i++) pthread_create(&philo[i],NULL,philosopher,(void*)i); for (i=0;i<PHILOS;i++) pthread_join(philo[i],NULL); return 0; } void * philosopher (void *num) { int id; int i,left_chopstick,right_chopstick,f; id=(int)num; printf("Philosopher %d is done thinking and now ready to eat\n ",id); right_chopstick=id; left_chopstick=id+1; //wrap around the chopsticks if (left_chopstick==PHILOS) left_chopstick=0; while (f=food_on_table()) { /*thanks to philosophers#1 who would like to take a nap *before picking up the chopsticks,the other philosophers *may be able to eat their dishes and not deadlock */ if (id==0) sleep(sleep_seconds); grab_chopstick(id,right_chopstick,"right"); usleep(DELAY *(FOOD -f +1)); grab_chopstick(id,left_chopstick,"left"); printf("Philosopher %d:eating\n",id); usleep(DELAY *(FOOD -f +1)); down_chopsticks(left_chopstick,right_chopstick); } printf("Philosopher %d is done eating \n",id); return (NULL); } int food_on_table () { static int food=FOOD; int myfood; pthread_mutex_lock(&food_lock); if(food>0) { food--; } myfood=food; pthread_mutex_unlock(&food_lock); return myfood; } void grab_chopstick(int phi1, int c,
1 0
- 经典同步问题linux下的C实现:生产者-消费者问题,读者-写者问题,哲学家问题
- 经典同步问题linux下的C实现:生产者-消费者问题,读者-写者问题,哲学家问题
- 经典的IPC问题 -- 哲学家就餐问题、读者-写者问题、理发师睡觉问题、生产者-消费者问题详解
- 操作系统进程同步三大问题:生产者消费者,哲学家进餐,读者写者问题
- C语言:生产者-消费者问题、读者-写者问题
- Java实现生产者消费者问题与读者写者问题
- Java实现生产者消费者问题与读者写者问题
- 第二章 经典同步问题1(生产者消费者、读者写者)
- 生产者消费者问题与读者写者问题---信号量机制
- 操作系统中,生产者消费者问题&读者写者问题
- 进程同步问题(1)——生产者,消费者 & 读者,写者问题
- Linux下生产者-消费者问题的实现
- linux下生产者消费者问题的实现
- linux系统生产者-消费者,读者-写者,哲学家就餐 C语言实现
- 生产者-消费者问题实现 (linux下C同步信号量和互斥信号量的应用)
- 操作系统笔记《7》-------生产者、消费者问题 。读者、写者问题 程序实现
- 经典进程同步问题-生产者消费者问题
- Linux平台下线程同步,实现“生产者消费者问题”
- 元素为结构体的vector 找最大元素
- FileAssociation
- 给儿子制定的学习、活动计划(2015.02 -)
- ini, Reg
- wsFile
- 经典同步问题linux下的C实现:生产者-消费者问题,读者-写者问题,哲学家问题
- wsArray
- Mybatis3源码分析(三):解析mapper的xml配置文件
- Java核心技术再理解——深入浅出Java多线程
- wsPlot
- wsPanelView
- wsProgressBar
- wsSlider
- POJ 1990-MooFest(树状数组)