/*=============================================================== * 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); }
/*=============================================================== * 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); }