经典同步问题linux下的C实现:生产者-消费者问题,读者-写者问题,哲学家问题
2013-04-11 22:36
661 查看
1.生产者-消费者问题
2.读者-写者问题
3.哲学家进餐问题
有一点要注意:
就是循环生生成线程时,要给线程处理函数传入计数器参数时,不能直接用计数器的地址——因为计数器会现在主函数中改变。显然也不能用循环中的临时变量来记录。所以只好再有外部数组来记录这些实参值了。
/*=============================================================== * 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); }
相关文章推荐
- 经典同步问题linux下的C实现:生产者-消费者问题,读者-写者问题,哲学家问题
- 经典的IPC问题 -- 哲学家就餐问题、读者-写者问题、理发师睡觉问题、生产者-消费者问题详解
- linux系统生产者-消费者,读者-写者,哲学家就餐 C语言实现
- 进程同步的几个经典题目-生产者消费者-哲学家进餐-读者写者
- 操作系统进程同步三大问题:生产者消费者,哲学家进餐,读者写者问题
- Java 5种方法实现生产者消费者问题与2种方法实现读者写者问题
- Java实现生产者消费者问题与读者写者问题
- 进程、线程知识点总结和同步(消费者生产者,读者写者三类问题)、互斥、异步、并发、并行、死锁、活锁的总结
- linux下多线程互斥量实现生产者--消费者问题和哲学家就餐问题
- 进程同步问题(1)——生产者,消费者 & 读者,写者问题
- Java实现生产者消费者问题与读者写者问题
- 操作系统笔记《7》-------生产者、消费者问题 。读者、写者问题 程序实现
- 操作系统清华大学版笔记(十) 信号量、管程、条件互斥、经典同步问题(读者写者、哲学家问题)
- JAVA多线程经典问题 -- 生产者 消费者 同步队列实现方法
- Java实现生产者消费者问题与读者写者问题
- Linux下信号量实现进程同步、互斥(生产者消费者问题)
- Java实现生产者消费者问题与读者写者问题详解
- Java实现生产者消费者问题与读者写者问题
- 生产者-消费者问题实现 (linux下C同步信号量和互斥信号量的应用)
- 进程、线程知识点总结和同步(消费者生产者,读者写者三类问题)、互斥、异步、并发、并行、死锁、活锁的总结