生产者消费者

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <unistd.h>
  4 #include <pthread.h>
  5 #include <semaphore.h>
  6 #include <time.h>
  7 
  8 #define N 30   // 消费者或者生产者的数目
  9 #define M 30 // 缓冲数目
 10 
 11 int in = 0;   // 生产者放置产品的位置,下一个空位
 12 int out = 0; // 消费者取产品的位置,第一个非空位
 13 int k = 0, m = 0, count = 0, a[30], products_sum = 1, count_rnd = 0, j = 0;
 14 
 15 char buffer[M];// 缓冲初始化为0, 开始时没有产品
 16 char consumer_store[1000];
 17 
 18 sem_t empty_sem; // 同步信号量
 19 sem_t full_sem;   // 同步信号量
 20 pthread_mutex_t mutex; // 互斥信号量
 21 
 22 int producer_num = 1;   //生产者id
 23 int consumer_num = 1; //消费者id
 24 
 25 /* 打印缓冲情况 */
 26 void print(){
 27     int i;
 28     printf("\033[33m缓冲区中剩余产品: \033[0m\n");
 29     for(i = 0; i < M; i++)
 30         printf("\033[33m%c \033[0m", buffer[i]);
 31     printf("\n");
 32 }
 33 
 34 void print_consumer(){
 35     int i;
 36     for(i = 0; i < M; i++)
 37         printf("%c", consumer_store[i]);
 38     printf("\n");
 39 }
 40 
 41 /* 生产者方法 */
 42 void *product(){  
 43      sem_wait(&empty_sem);
 44      pthread_mutex_lock(&mutex);
 45      buffer[in] = 'A' + count;
 46      count++;
 47      printf("生产者 %d 生产产品 %c 放入缓冲区 %d \n",producer_num, buffer[in], in); 
 48      in++;
 49      in=in%M;
 50      producer_num++;
 51      pthread_mutex_unlock(&mutex);
 52      sem_post(&full_sem);
 53 }
 54 /* 消费者方法 */
 55 void *prochase(){
 56     sleep(1);
 57      sem_wait(&full_sem);           //获取信号量
 58      pthread_mutex_lock(&mutex);    //加锁
 59      int n = 0, l = 0, p = 0;
 60      j=(rand() % 30) + 1;
 61      if(count_rnd == 0){
 62          a[m] = j;
 63          m++;
 64      }
 65      else{
 66          while(n < m){
 67              if(a[n] != j)
 68                  n++;
 69              else{
 70                  j=(rand() % 30) + 1;
 71                  n = 0;
 72              }
 73          }
 74      }
 75      a[m] = j;
 76      m++;
 77      if(consumer_num % 2 != 0) {         //奇数号消费者
 78          if(consumer_num == 29) {  //所有奇数号消费者都消费之后,1,3,5,7,9号产品从缓冲区撤销
 79              buffer[0] = ' ';
 80              buffer[2] = ' ';
 81              buffer[4] = ' ';
 82              buffer[6] = ' ';
 83              buffer[8] = ' ';
 84          }
 85          if(j == 1 || j == 3 || j == 5 || j == 7 || j == 9)  { //1,3,5,7,9号生产者供奇数号消费者消费
 86              printf("\033[35;4m消费者 %d 消费由生产者  %d 生产的 %c\033[0m\n", consumer_num, j, buffer[j-1]);
 87          }
 88          else if((j>1&&j<11&&j%2 == 0) || (j>10&&j<21&&consumer_num != j)) { 
 89              printf("消费者 %d 不能消费由生产者 %d 生产的产品!\n", consumer_num, j);
 90              j=(rand() % 30) + 1;
 91              while((j>1&&j<11&&j%2 == 0) || (j>10&&j<21&&consumer_num != j)){
 92                  j=(rand() % 30) + 1;
 93              }
 94              while(buffer[j-1] == ' '){
 95                  j=(rand() % 30) + 1;
 96              }
 97              a[m] = j;
 98              printf("\033[35;4m消费者 %d 消费由生产者  %d 生产的 %c\033[0m\n", consumer_num, j, buffer[j-1]);
 99              buffer[j-1] = ' ';
100          }
101          else if(j>10&&j<21&&consumer_num == j){//11-20号生产者只供对应编号相同的消费者消费
102          
103              printf("\033[35;4m消费者 %d 消费由生产者  %d 生产的 %c\033[0m\n", consumer_num, j, buffer[j-1]);
104              buffer[j-1] = ' ';
105          }
106          else{   //其他任意编号的生产者被随意消费
107             printf("\033[35;4m消费者 %d 消费由生产者  %d 生产的 %c\033[0m\n", consumer_num, j, buffer[j-1]);
108             buffer[j-1] = ' ';
109          }
110      }
111      else{   //偶数号消费者
112         if(j == 2 || j == 4 || j == 6 || j == 8 || j == 10){ //2,4,6,8,10号生产者被所有偶数号消费者消费
113             printf("\033[35;4m消费者 %d 消费由生产者  %d 生产的 %c\033[0m\n", consumer_num, j, buffer[j-1]);
114             buffer[j-1] = ' ';
115          }
116          else if((j > 0 && j < 10 && j % 2 != 0) || (j > 10 && j < 21 && consumer_num != j)){
117              printf("消费者 %d 不能消费由生产者 %d 生产的产品!\n",consumer_num,j);
118              j=(rand() % 30) + 1;
119              while((j > 0 && j < 10 && j % 2 != 0) || (j > 10 && j < 21 && consumer_num != j)) {
120                 j=(rand() % 30) + 1;
121              }
122              while(buffer[j-1] == ' '){
123                  j=(rand() % 30) + 1;
124              }
125              a[m] = j;
126              printf("\033[35;4m消费者 %d 消费由生产者  %d 生产的 %c\033[0m\n", consumer_num, j, buffer[j-1]);
127              buffer[j-1] = ' ';
128          }
129          else if(j>10&&j<21&&consumer_num == j) {    //11-20编号的生产者供对应编号相同的消费者消费
130             printf("\033[35;4m消费者 %d 消费由生产者  %d 生产的 %c\033[0m\n", consumer_num, j, buffer[j-1]);
131              buffer[j-1] = ' ';
132          }
133          else{
134              printf("\033[35;4m消费者 %d 消费由生产者  %d 生产的 %c\033[0m\n", consumer_num, j, buffer[j-1]);
135              buffer[j-1] = ' ';
136          }
137      }
138      buffer[j-1] = ' ';
139      print();
140      out++;
141      out=out % M;
142      consumer_num++;
143      count_rnd++;
144      pthread_mutex_unlock(&mutex);
145      sem_post(&empty_sem);
146 }
147 
148 int main(){
149     pthread_t id1[N];
150     pthread_t id2[N];
151     int i;
152     int ret[N];
153     srand((unsigned)time(0));
154     // 初始化同步信号量
155      int ini1 = sem_init(&empty_sem, 0, M);
156      int ini2 = sem_init(&full_sem, 0, 0);  
157      if(ini1 && ini2 != 0){
158         printf("sem init failed \n");
159         exit(1);
160      }
161      //初始化互斥信号量
162      int ini3 = pthread_mutex_init(&mutex, NULL);
163      if(ini3 != 0){
164         printf("mutex init failed \n");
165         exit(1);
166      }
167      // 每个生产者生产30个消息后结束运行
168      while(products_sum <= 30){
169          //创建N个生产者线程
170          for(i = 0; i < N; i++){
171             ret[i] = pthread_create(&id1[i], NULL, product, (void *)(&i));
172             if(ret[i] != 0){
173                 printf("product %d creation failed \n", i);
174                 exit(1);
175             }
176         }
177      //创建N个消费者线程
178         for(i = 0; i < N; i++){
179              ret[i] = pthread_create(&id2[i], NULL, prochase, NULL);
180              if(ret[i] != 0){
181                  printf("prochase %d creation failed \n", i);
182                  exit(1);
183             }
184         }
185          for(i = 0; i < N; i++){
186              pthread_join(id1[i], NULL);
187              pthread_join(id2[i], NULL);
188         }
189          
190          printf("++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
191          printf("完成第 %d 次生产\n",products_sum);
192          printf("++++++++++++++++++++++++++++++++++++++++++++++++++++++\n\n");
193          products_sum++;
194          in = 0;
195          out = 0;
196          count = 0;
197          consumer_num = 1;
198          producer_num = 1;
199          count_rnd = 0;
200          m = 0;
201          a[30] = ' ';
202      }
203      sem_destroy(&empty_sem);
204      sem_destroy(&full_sem);
205      exit(0);    
206 }

 

posted @ 2013-12-31 16:26  Haos  阅读(215)  评论(0)    收藏  举报