码迷,mamicode.com
首页 > 编程语言 > 详细

跟我一起做面试题-linux线程编程(5)

时间:2014-09-03 12:53:56      阅读:343      评论:0      收藏:0      [点我收藏+]

标签:des   style   blog   http   color   os   io   ar   for   

如题所述:

生产者消费者问题

这是一个非常经典的多线程题目,题目大意如下:有一个生产者在生产产品,这些产品将提供给若 干个消费者去消费,为了使生产者和消费者能并发执行,在两者之间设置一个有多个缓冲区的缓冲池,生产者将它生产的产品放入一个缓冲区中,消费者可以从缓冲 区中取走产品进行消费,所有生产者和消费者都是异步方式运行的,但它们必须保持同步,即不允许消费者到一个空的缓冲区中取产品,也不允许生产者向一个已经 装满产品且尚未被取走的缓冲区中投放产品。

 

bubuko.com,布布扣
  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <string.h>
  4 #include <pthread.h>
  5 #include <errno.h>
  6 #include <stdarg.h>
  7 #include <unistd.h>
  8 #include <limits.h>
  9 #include <sys/ipc.h>
 10 #include <sys/msg.h>
 11 #include <sys/types.h>  
 12 #include <sys/time.h>
 13 #include <signal.h>
 14  
 15  
 16 #define FULL    5           // 仓库满状态,抢iphone哟,这么少
 17 #define EMPTY   0           //  仓库空状态
 18 #define INIT_DEPOT_NUM  2   // 初始仓库状态
 19 #define CONSUMER_NUM 9     //  消费者数量 
 20 #define PRODUCER_NUM 1      // 生产者数量
 21 #define RUN     0           //  系统运行状态
 22 #define OVER    1           // 系统关闭状态
 23 
 24 int product;                //  具体仓库里的产品
 25 int shutdown;
 26 pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER;
 27 pthread_cond_t  product_cond = PTHREAD_COND_INITIALIZER;
 28 pthread_cond_t  consume_cond = PTHREAD_COND_INITIALIZER;
 29 
 30 
 31 #define myprintf( ... )  32     do{  33     mprintf(__FILE__, __FUNCTION__, __LINE__,##__VA_ARGS__);  34     }while(0)
 35 
 36 
 37 
 38 
 39 int mprintf(const char *file_name, const char *func_name, int line, const char *fmt, ...)
 40 {
 41     va_list     strArgPtr;
 42     int la,lb;
 43     la = fprintf(stdout, "[%-15s]-[%-10s]-[%04d]", file_name, func_name, line);
 44     va_start(strArgPtr, fmt);
 45     lb = vfprintf(stdout, fmt, strArgPtr);
 46     va_end(strArgPtr);
 47     printf("\n");
 48     fflush(stdout);
 49     return (la+lb);
 50 }
 51 
 52 void * fun_producer(void *arg)
 53 {
 54     int i;
 55     int name = (int)arg;
 56     for(;;)
 57     {
 58             if( pthread_mutex_lock(&mylock))
 59             {
 60                 myprintf("pthread_mutex_lock error errmsg[%s]\n", strerror(errno));
 61                 exit(0);
 62             }
 63             while(1)
 64             {
 65                 if(shutdown == OVER)
 66                 {
 67                     myprintf("producer id [%d] go home now", name);
 68                     if(pthread_mutex_unlock(&mylock))
 69                     {
 70                         myprintf("pthread_mutex_unlock error errmsg[%s]\n", strerror(errno));
 71                         exit(0);
 72                     }
 73                     pthread_exit(NULL);    
 74                 }
 75                 if ( product >= FULL)
 76                 {
 77                      myprintf("producer id [%d] prompt depot full [%d]",name, product);
 78                      break;
 79                 }
 80                 else
 81                 {
 82                     product++;
 83                     myprintf("producer id [%d] put product [%d] into depot",name, product);
 84                     break;
 85                 }
 86                         
 87                 if(pthread_cond_wait(&product_cond, &mylock))
 88                 {
 89                     myprintf("wait error errmsg[%s]\n", strerror(errno));
 90                     exit(0);
 91                 }
 92             }
 93             if(pthread_mutex_unlock(&mylock))
 94             {
 95                 myprintf("pthread_mutex_unlock error errmsg[%s]\n", strerror(errno));
 96                 exit(0);
 97             }
 98             if(pthread_cond_broadcast(&consume_cond))
 99             {
100                 myprintf("pthread_cond_broadcast error errmsg[%s]\n", strerror(errno));
101                 exit(0);
102             }
103             //sleep(1);
104     }
105 }
106 
107 void * fun_consumer(void *arg)
108 {
109     int i;
110     int name = (int)arg;
111     for(;;)
112     {
113             if( pthread_mutex_lock(&mylock))
114             {
115                 myprintf("pthread_mutex_lock error errmsg[%s]\n", strerror(errno));
116                 exit(0);
117             }
118             while(1)
119             {
120                 if(shutdown == OVER)
121                 {
122                     myprintf("consumer id [%d] go home now", name);
123                     if(pthread_mutex_unlock(&mylock))
124                     {
125                         myprintf("pthread_mutex_unlock error errmsg[%s]\n", strerror(errno));
126                         exit(0);
127                     }
128                     pthread_exit(NULL);    
129                 }
130                 if ( product > EMPTY)
131                 {
132                      myprintf("consumer id [%d] take product from depot [%d]", name, product);
133                      product--;
134                      break;
135                 }      
136                 if(pthread_cond_wait(&consume_cond, &mylock))
137                 {
138                     myprintf("wait error errmsg[%s]\n", strerror(errno));
139                     exit(0);
140                 }
141             }
142             if(pthread_mutex_unlock(&mylock))
143             {
144                 myprintf("pthread_mutex_unlock error errmsg[%s]\n", strerror(errno));
145                 exit(0);
146             }
147             if(pthread_cond_broadcast(&product_cond))
148             {
149                 myprintf("pthread_cond_broadcast error errmsg[%s]\n", strerror(errno));
150                 exit(0);
151             }
152             //sleep(1);
153     }
154 }
155 
156 void allover(int sig)
157 {
158         if( pthread_mutex_lock(&mylock))
159         {
160             myprintf("pthread_mutex_lock error errmsg[%s]\n", strerror(errno));
161             exit(0);
162         }
163         shutdown = OVER;
164         if( pthread_mutex_unlock(&mylock))
165         {
166             myprintf("pthread_mutex_lock error errmsg[%s]\n", strerror(errno));
167             exit(0);
168         }
169         if(pthread_cond_broadcast(&consume_cond))
170         {
171             myprintf("pthread_cond_broadcast error errmsg[%s]\n", strerror(errno));
172             exit(0);
173         }
174         if(pthread_cond_broadcast(&product_cond))
175         {
176             myprintf("pthread_cond_broadcast error errmsg[%s]\n", strerror(errno));
177             exit(0);
178         }
179 }
180 
181 
182 int appInit()
183 {
184     shutdown = RUN;
185     int i;
186     product = INIT_DEPOT_NUM;
187     if ( signal(SIGUSR1, allover)== SIG_ERR)
188     {
189         myprintf("signal  failure");    
190         return -1;    
191     }
192     if ( signal(SIGTERM, allover)== SIG_ERR)
193     {
194         myprintf("signal  failure");    
195         return -1;    
196     }
197     if ( signal(SIGINT, allover)== SIG_ERR)
198     {
199         myprintf("signal  failure");    
200         return -1;    
201     }
202     if ( signal(SIGQUIT, allover)== SIG_ERR)
203     {
204         myprintf("signal  failure");    
205         return -1;    
206     }
207 //    pthread_mutex_init(&mylock, NULL);
208 //    pthread_cond_init(&cond, NULL);
209     return 0; 
210 }
211 
212 int appDone()
213 {
214     int i;
215 //    pthread_cond_destroy(&cond);
216 //    pthread_mutex_destroy(&mylock);
217     return 0;
218 }
219 
220 int main(int argc, char *argv[])
221 {
222  
223     pthread_t consumer[CONSUMER_NUM];
224     pthread_t producer[PRODUCER_NUM];
225 
226     int ret;
227     int i;
228     ret = appInit();
229     if(ret)
230     {
231         myprintf("appinit failure");
232         return -1;    
233     }
234     
235     for( i = 0; i < CONSUMER_NUM; i++)
236     {
237         ret = pthread_create(&consumer[i], NULL, fun_consumer, (void*)i);
238         if(ret)
239         {
240             myprintf("pthread_create ta error [%s]", strerror(errno));
241             return 1;
242         }        
243     }
244     
245     for( i = 0; i < PRODUCER_NUM; i++)
246     {
247         ret = pthread_create(&producer[i], NULL, fun_producer, (void*)i);
248         if(ret)
249         {
250             myprintf("pthread_create ta error [%s]", strerror(errno));
251             return 1;
252         }         
253     }
254     for( i = 0; i < CONSUMER_NUM; i++)
255         pthread_join(consumer[i], NULL);
256     for( i = 0; i < PRODUCER_NUM; i++)
257         pthread_join(producer[i], NULL);
258 
259     myprintf("main thread exit");
260     ret = appDone();
261     if(ret)
262     {
263         myprintf("appDone failure");
264         return -1;    
265     }
266     return 0;
267 }
View Code

代码一般在以前的基础上更改,有些bug的修复并不会同步到之前的版本。以最新版本为要。

本版本增加一个控制,对一些常用信号给出响应,并结束程序。



 

跟我一起做面试题-linux线程编程(5)

标签:des   style   blog   http   color   os   io   ar   for   

原文地址:http://www.cnblogs.com/boota/p/3953297.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!