Chinaunix首页 | 论坛 | 博客
  • 博客访问: 7723602
  • 博文数量: 961
  • 博客积分: 15795
  • 博客等级: 上将
  • 技术积分: 16612
  • 用 户 组: 普通用户
  • 注册时间: 2010-08-07 14:23
文章分类

全部博文(961)

文章存档

2016年(1)

2015年(61)

2014年(41)

2013年(51)

2012年(235)

2011年(391)

2010年(181)

分类: LINUX

2011-06-19 14:29:57

  1. /*
  2.  * 线程同步——条件变量
  3.  * 生产者——消费者
  4.  * Lzy 2011-6-19
  5.  */

  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <pthread.h>

  9. int x = 0;                //定义全局变量
  10. pthread_mutex_t    mutex = PTHREAD_MUTEX_INITIALIZER;    //静态初始化互斥量
  11. pthread_cond_t cond = PTHREAD_COND_INITIALIZER;    //静态初始化条件变量

  12. void *producer(void *arg)
  13. {
  14.     while(1)
  15.     {
  16.         pthread_mutex_lock(&mutex);    //对互斥量上锁
  17.         
  18.         while(5-x > 0)
  19.         {
  20.             x++;
  21.             printf("Producing: %d\n",x);            
  22.             sleep(1);
  23.         }
  24.         if(x == 5)
  25.             pthread_cond_signal(&cond);        //激活等待的线程
  26.             
  27.         pthread_mutex_unlock(&mutex);    //对互斥量解锁
  28.         sleep(1);
  29.     }

  30.     pthread_exit(NULL);
  31. }

  32. void *consumer(void *arg)
  33. {
  34.     while(1)
  35.     {
  36.         pthread_mutex_lock(&mutex);    //对互斥量上锁        
  37.         pthread_cond_wait(&cond, &mutex);    //条件等待
  38.         
  39.         while(x > 0)
  40.         {
  41.             x--;
  42.             printf("Consumer: %d\n",x);            
  43.             sleep(1);
  44.         }
  45.         
  46.         pthread_mutex_unlock(&mutex);    //对互斥量解锁
  47.         sleep(1);
  48.     }

  49.     pthread_exit(NULL);
  50. }

  51. int main(void)
  52. {
  53.     pthread_t tidpro, tidcon;

  54.     pthread_create(&tidpro, NULL, producer, NULL);        //创建生产者线程
  55.     pthread_create(&tidcon, NULL, consumer, NULL);        //创建消费者线程

  56.     pthread_exit(NULL);        //等待线程退出

  57.     return 0;
  58. }
  1. /*
  2.  * 生产者——消费者模型
  3.  * 使用多线程实现生产者与消费者模型,产品缓冲区使用循环队列
  4.  * Lzy 2011-6-19
  5.  */

  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <pthread.h>
  10. #include <time.h>
  11. #include <unistd.h>
  12. #include <errno.h>

  13. #define PRODUCE_EXIT    '~'    //produce thread exit flag
  14. #define CONSUME_EXIT    '@'    //consume thread exit flag
  15. #define BSIZE             20
  16. #define PRODUCER_NUM    3        //定义3个生产者
  17. #define CONSUMER_NUM    3        //定义5个消费者

  18. typedef struct buffer_t
  19. {
  20.     char            buf[BSIZE];
  21.     int                occupied;    //product number
  22.     int                nextin;
  23.     int                nextout;
  24.     pthread_mutex_t    mutex;
  25.     pthread_cond_t    less;
  26.     pthread_cond_t    more;
  27. }buffer_t;

  28. buffer_t ware;
  29. pthread_once_t once = PTHREAD_ONCE_INIT;

  30. void init(void)
  31. {
  32.     bzero(&ware, sizeof(ware));                //清0
  33.     pthread_mutex_init(&ware.mutex, NULL);        //初始化互斥锁
  34.     pthread_cond_init(&ware.less, NULL);        //初始化消费者条件变量
  35.     pthread_cond_init(&ware.more, NULL);        //初始化生产者条件变量
  36. }

  37. void destroy(void)
  38. {
  39.     pthread_mutex_destroy(&ware.mutex);        //注销互斥锁
  40.     pthread_cond_destroy(&ware.less);        //注销消费者条件变量
  41.     pthread_cond_destroy(&ware.more);        //注销生产者条件变量
  42. }

  43. void *producer(void *arg)            //生产者线程运行函数
  44. {
  45.     char c;
  46.     struct timespec tt;
  47.     
  48.     while(1)
  49.     {
  50.         if((c = getchar()) != '\n')
  51.         {
  52.             if(c == PRODUCE_EXIT)        
  53.                 break;                //结束循环
  54.                 
  55.             pthread_mutex_lock(&ware.mutex);    //互斥锁上锁
  56.             
  57.             if(ware.occupied >= BSIZE)            //空间已满
  58.             {
  59.                 tt.tv_sec = time(NULL) + 1;        //等待时间为3秒
  60.                 tt.tv_nsec = 0;
  61.                 
  62.                 if(pthread_cond_timedwait(&ware.more, &ware.mutex, &tt) == ETIMEDOUT)    //阻塞
  63.                 {
  64.                     pthread_mutex_unlock(&ware.mutex);    //互斥锁解锁
  65.                     continue;
  66.                 }
  67.             }    
  68.             
  69.             ware.buf[ware.nextin] = c;    //写入字符
  70.             ware.nextin = (ware.nextin + 1) % BSIZE;    
  71.             ware.occupied++;            //总数量加一        
  72.             
  73.             printf("produce: [tid=%u] [%c].\n",pthread_self(), c);        

  74.             pthread_cond_signal(&ware.less);    //激活消费者线程    
  75.             pthread_mutex_unlock(&ware.mutex);    //互斥锁解锁            
  76.         }
  77.         sleep(1);
  78.     }
  79.     
  80.     printf("produce [tid=%u] EXIT.\n", pthread_self());
  81.     pthread_exit(NULL);    
  82. }

  83. void *consumer(void *arg)            //消费者线程运行函数
  84. {
  85.     char c;
  86.     struct timespec tt;
  87.     
  88.     while(1)
  89.     {
  90.         pthread_mutex_lock(&ware.mutex);    //互斥锁上锁
  91.         
  92.         if(ware.occupied <= 0)            //空间已空
  93.         {            
  94.             tt.tv_sec = time(NULL) + 1;        //等待时间为3秒
  95.             tt.tv_nsec = 0;
  96.             
  97.             if(pthread_cond_timedwait(&ware.less, &ware.mutex, &tt) == ETIMEDOUT)    //阻塞        
  98.             {
  99.                 pthread_mutex_unlock(&ware.mutex);    //互斥锁解锁
  100.                 continue;
  101.             }
  102.         }    
  103.         
  104.         c = ware.buf[ware.nextout];    //输出字符            
  105.         ware.nextout = (ware.nextout + 1) % BSIZE;            
  106.         ware.occupied--;            //总数量减一
  107.         
  108.         printf("consumer: [tid=%u] [%c].\n",pthread_self(), c);        
  109.     
  110.         pthread_cond_signal(&ware.more);    //激活生产者线程    
  111.         pthread_mutex_unlock(&ware.mutex);    //互斥锁解锁
  112.         
  113.         if(c == CONSUME_EXIT)
  114.             break;
  115.             
  116.         sleep(1);
  117.     }
  118.     
  119.     printf("consume [tid=%u] EXIT.\n", pthread_self());
  120.     pthread_exit(NULL);    
  121. }

  122. int main(void)
  123. {
  124.     int i;
  125.     
  126.     pthread_t tid[PRODUCER_NUM + CONSUMER_NUM];        //定义线程描述符    
  127.     pthread_once(&once, init);                        //控制初始化例程只被执行一次
  128.     
  129.     for(i = 0; i < PRODUCER_NUM; i++)
  130.         pthread_create(&tid[i], NULL, producer, NULL);        //创建生产者线程
  131.     
  132.     for(i = 0; i < CONSUMER_NUM; i++)
  133.         pthread_create(&tid[i], NULL, consumer, NULL);        //创建消费者线程    
  134.     
  135.     pthread_exit(NULL);            //等待所有线程退出
  136.     destroy();                    //注销
  137.     
  138.     return 0;
  139. }
阅读(2463) | 评论(0) | 转发(4) |
给主人留下些什么吧!~~