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

来源:互联网 发布:mac air能玩什么游戏 编辑:程序博客网 时间:2024/04/30 18:29

http://blog.csdn.net/life_hunter/article/details/8790553


1.生产者-消费者问题

[cpp] view plaincopy
  1. /*=============================================================== 
  2.  
  3.  * File Name : producerConsumerProblem.c 
  4.  * Creation Date : 2013-04-11 
  5.  * Last Modified : 2013年04月11日 星期四 20时53分13秒 
  6.  * Purpose :test linux semaphore usage 
  7.  
  8. ================================================================*/  
  9. #include <stdio.h>  
  10. #include <sys/types.h>  
  11. #include <semaphore.h>  
  12. #include <pthread.h>  
  13. #include <stdlib.h>  
  14.   
  15. void *producer_handler(void *ptr);  
  16. void *consumer_handler(void *ptr);  
  17.   
  18. sem_t mutex,blank,fill;  
  19. int *buffer;  
  20. int in=0,out=0,buffer_size=10;  
  21.   
  22. void main()  
  23. {  
  24.     if((buffer=(int *)malloc(buffer_size*sizeof(int)))==NULL)  
  25.         printf("can't allocate memroy on heap\n");  
  26.     sem_init(&mutex,0,1);  
  27.     sem_init(&blank,0,buffer_size);  
  28.     sem_init(&fill,0,0);  
  29.   
  30.     int err;  
  31.     pthread_t producer,consumer;  
  32.     err=pthread_create(&producer,NULL,producer_handler,NULL);  
  33.     if(err!=0)  
  34.         err_quit("can't create thread: %s\n",strerror(err));  
  35.     err=pthread_create(&consumer,NULL,consumer_handler,NULL);  
  36.     if(err!=0)  
  37.         err_quit("can't create thread: %s\n",strerror(err));  
  38.   
  39.     sleep(10);  
  40.   
  41. }  
  42.   
  43. void *producer_handler(void *ptr)  
  44. {  
  45.     while(1){  
  46.         static int data=0;  
  47.         sem_wait(&blank);  
  48.     //  sem_wait(&mutex);  
  49.       
  50.         buffer[in]=++data;  
  51.         printf("%d has been input to the buffer\n",data);  
  52.         in=(in+1+buffer_size)%buffer_size;  
  53.     //  sem_post(&mutex);  
  54.         sem_post(&fill);  
  55.         sleep(1);  
  56.     }  
  57.     return ((void *)0);  
  58. }  
  59.   
  60. void *consumer_handler(void *ptr)  
  61. {  
  62.     while(1){  
  63.         int fetch;  
  64.         sem_wait(&fill);  
  65.     //  sem_wait(&mutex);  
  66.         fetch=buffer[out];  
  67.         out=(out+1+buffer_size)%buffer_size;  
  68.         printf("%d has been fetched\n",fetch);  
  69.     //  sem_post(&mutex);  
  70.         sem_post(&blank);  
  71.         sleep(2);  
  72.     }  
  73.     return ((void *)0);  
  74. }  

2.读者-写者问题

[cpp] view plaincopy
  1. /*=============================================================== 
  2.  
  3.  * File Name : readerWriterProblem.c 
  4.  * Creation Date : 2013-04-11 
  5.  * Last Modified : 2013年04月11日 星期四 22时42分45秒 
  6.  * Purpose : 
  7.  
  8. ================================================================*/  
  9.   
  10. #include <stdio.h>  
  11. #include <sys/types.h>  
  12. #include <semaphore.h>  
  13. #include <pthread.h>  
  14. #include <stdlib.h>  
  15.   
  16. #define READER_NUM 5  
  17. void *reader_handler(void *ptr);  
  18. void *writer_handler(void *ptr);  
  19.   
  20. sem_t write_mutex;  
  21. sem_t mutex;  
  22. int read_count;  
  23.   
  24. void main()  
  25. {  
  26.     sem_init(&write_mutex,0,1);  
  27.     sem_init(&mutex,0,1);  
  28.     read_count=0;  
  29.       
  30.     int err,i;  
  31.     pthread_t reader[READER_NUM],writer;  
  32.     int args[READER_NUM];  
  33.     for(i=0;i<READER_NUM;++i){  
  34.         args[i]=i;  
  35.         err=pthread_create(&reader[i],NULL,reader_handler,(void*)&args[i]);  
  36.         if(err!=0)  
  37.             err_quit("can't create thread: %s\n",strerror(err));  
  38.     }  
  39.     err=pthread_create(&writer,NULL,writer_handler,NULL);  
  40.     if(err!=0)  
  41.         err_quit("can't create thread: %s\n",strerror(err));  
  42.   
  43.     sleep(10);  
  44.   
  45. }  
  46.   
  47. void *reader_handler(void *ptr)  
  48. {  
  49.     while(1){  
  50.         if(read_count==0){  
  51.             sem_wait(&write_mutex);  
  52.         }  
  53.         sem_wait(&mutex);  
  54.         ++read_count;  
  55.         sem_post(&mutex);  
  56.   
  57.         printf("There are %d readers reading\n",read_count);  
  58.         sleep(1);  
  59.   
  60.         sem_wait(&mutex);  
  61.         --read_count;  
  62.         sem_post(&mutex);  
  63.   
  64.         if(read_count==0){  
  65.             sem_post(&write_mutex);  
  66.         }  
  67.         sleep(1);  
  68.     }  
  69.     return ((void *)0);  
  70. }  
  71.   
  72. void *writer_handler(void *ptr)  
  73. {  
  74.     while(1){  
  75.         if(read_count==0){  
  76.             sem_wait(&write_mutex);  
  77.             printf("Writer writes\n");  
  78.             sem_post(&write_mutex);  
  79.         }  
  80.         else  
  81.             printf("Writer failed\n");  
  82.         sleep(1);  
  83.     }  
  84.     return ((void *)0);  
  85. }  


3.哲学家进餐问题

有一点要注意:

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

[cpp] view plaincopy
  1. /*=============================================================== 
  2.  
  3.  * File Name : dinningPhilosophersProblem.c 
  4.  * Creation Date : 2013-04-11 
  5.  * Last Modified : 2013年04月11日 星期四 21时34分18秒 
  6.  * Purpose : 
  7.  
  8. ================================================================*/  
  9.   
  10. #include <stdio.h>  
  11. #include <sys/types.h>  
  12. #include <semaphore.h>  
  13. #include <pthread.h>  
  14. #include <stdlib.h>  
  15.   
  16. #define PHILO_NUM 5  
  17. void *philosopher(void *arg);  
  18.   
  19. sem_t sema[PHILO_NUM];  
  20. sem_t mutex;  
  21. void main()  
  22. {  
  23.     int i,err;  
  24.     int args[PHILO_NUM];  
  25.     for(i=0;i<PHILO_NUM;++i){  
  26.         sem_init(sema+i,0,1);  
  27.         args[i]=i;  
  28.     }    
  29.     sem_init(&mutex,0,1);  
  30.     pthread_t philosophers[PHILO_NUM];  
  31.     for(i=0;i<PHILO_NUM;++i){  
  32.         err=pthread_create(philosophers+i,NULL,philosopher,(void*)&args[i]);  
  33.         if(err!=0)  
  34.             err_quit("can't create thread: %s\n",strerror(err));  
  35.     }  
  36.     sleep(5);  
  37. }  
  38.   
  39. void *philosopher(void *arg)  
  40. {  
  41.     int num;  
  42.     num=*((int *)arg);  
  43.     //printf("Philosopher %d eats\n",num);  
  44.     while(1){  
  45.         sem_wait(&mutex);   
  46.         sem_wait(&sema[num]);  
  47.         sem_wait(&sema[(num+1)%PHILO_NUM]);  
  48.         sem_post(&mutex);  
  49.         printf("Philosopher %d eats\n",num);  
  50.         sem_post(&sema[num]);  
  51.         sem_post(&(sema[(num+1)%PHILO_NUM]));  
  52.         sleep(1);  
  53.     }  
  54.   
  55.     return ((void *)0);  
  56. }  



哲学家问题解决:
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
原创粉丝点击