织梦CMS - 轻松建站从此开始!

罗索

用Pthread Semophore实现生产者消费者同步

jackyhwei 发布于 2010-09-07 12:15 点击:次 
对于这个问题,可以创建四个线程:两个生产者(Provider)和两个消费者(Customer),它们分别进行将已使用的数字放入大小为8的缓冲区,和从缓冲区取出一个数字打印到屏幕上。假定每个生产者一次生产一个已被取出的数字,每个消费者一次取出一个数字打印到屏幕上。
TAG:

设计思路:
对于这个问题,可以创建四个线程:两个生产者(Provider)和两个消费者(Customer),它们分别进行将已使用的数字放入大小为8的缓冲区,和从缓冲区取出一个数字打印到屏幕上。假定每个生产者一次生产一个已被取出的数字,每个消费者一次取出一个数字打印到屏幕上。
具体实现时,我们将信号量(Semaphore)初始化为0,如此消费者必定需要等待生产者生产出至少一个资源才能使用资源。如此反复,实现同步。

源代码如下:
---------------

  1. /* 
  2. * File: aPthread.c 
  3. * How to Compile: gcc aPthread.c -pthread 
  4. * The solution of provider and cunstomer problem 
  5. * by using pthread methods 
  6. * 
  7. * By: YangQiang 
  8. * Date: 2008-11-24 
  9. */ 
  10.  
  11. #include <stdio.h> 
  12. #include <stdlib.h> 
  13.  
  14. #include <pthread.h> 
  15. #include <semaphore.h> 
  16.  
  17. // define the buffer size 
  18. #define BUFFERSIZE 8 
  19. // an array stores digits of number BUFFERSIZE 
  20. int bufArray[BUFFERSIZE]; 
  21.  
  22. // semaphore 
  23. sem_t mySem; 
  24.  
  25. // provider1 in the from small to large order 
  26. void provider1() 
  27.  int i; 
  28.  while ( 1 ) 
  29.  { 
  30.   // search for the resource to provide from small to large 
  31.   for ( i = 0; i < BUFFERSIZE; i++ ) 
  32.   { 
  33. if ( -1 == bufArray[i] ) 
  34.  printf("provider1 is working, it provided the number %d.\n", i); 
  35.  bufArray[i] = i; // provides the "resource" 
  36.  // add the semaphore by 1 
  37.  sem_post( &mySem ); 
  38.  break
  39.   } 
  40.  } 
  41.  
  42. // customer1 in the from small to large order 
  43. void customer1() 
  44.  int i; 
  45.  while ( 1 ) 
  46.  { 
  47.   sem_wait( &mySem ); // asks for the semaphore 
  48.   // search for the resource to consume from small to large 
  49.   for ( i = 0; i < BUFFERSIZE; i++ ) 
  50.   { 
  51. if ( -1 != bufArray[i] ) 
  52.  printf("customer1 is working, it consumed the number %d.\n", i); 
  53.  bufArray[i] = -1; // consumes the "resource"  
  54.  break
  55.   } 
  56.  } 
  57.  
  58. // provider2 in the from large to small order 
  59. void provider2() 
  60.  int i; 
  61.  while ( 1 ) 
  62.  { 
  63.   // search for the resource to provide from large to small 
  64.   for ( i = BUFFERSIZE - 1; i > -1; i-- ) 
  65.   { 
  66. if ( -1 == bufArray[i] ) 
  67.  printf("provider2 is working, it provided the number %d.\n", i); 
  68.  bufArray[i] = i; // provides the "resource" 
  69.  // add the semaphore by 1 
  70.  sem_post( &mySem ); 
  71.  break
  72.   } 
  73.  } 
  74.  
  75. // customer2 in the from large to small order 
  76. void customer2() 
  77.  int i; 
  78.  while ( 1 ) 
  79.  { 
  80.   sem_wait( &mySem ); // asks for the semaphore 
  81.   // search for the resource to consume from large to small 
  82.   for ( i = BUFFERSIZE - 1; i > -1; i-- ) 
  83.   { 
  84. if ( -1 != bufArray[i] ) 
  85.  printf("customer2 is working, it consumed the number %d.\n", i); 
  86.  bufArray[i] = -1; // consumes the "resource" 
  87.  break
  88.   } 
  89.  } 
  90.  
  91. int main() 
  92.  int i; 
  93.  pthread_t pro1, pro2, cus1, cus2; 
  94.  
  95.  // initialize the array 
  96.  for ( i = 0; i < BUFFERSIZE; i++ ) 
  97.   bufArray[i] = -1; 
  98.  
  99.  // initialize the semaphore 
  100.  sem_init( &mySem, 0, 0 ); 
  101.  
  102.  // appoint tasks to the four threads 
  103.  pthread_create( &pro1, NULL, (void *) provider1, NULL ); // provider1 
  104.  pthread_create( &pro2, NULL, (void *) provider2, NULL ); // provider2 
  105.  pthread_create( &cus1, NULL, (void *) customer1, NULL ); // customer1 
  106.  pthread_create( &cus2, NULL, (void *) customer2, NULL ); // customer2 
  107.  
  108.  // let the thread not to exit too early 
  109.  pthread_join( pro1, NULL ); 
  110.  pthread_join( pro2, NULL ); 
  111.  pthread_join( cus1, NULL ); 
  112.  pthread_join( cus2, NULL ); 
  113.  
  114.  return 0; 


-------------
执行结果:(程序循环执行过程中的一段)
从执行结果可以看到,两个生产者与两个消费者的执行顺序由于系统的调度而变得不确定, 但是两者之间是相互影响的,生产者需要生产消费者使用完的资源,消费者只能使用生产者已经生产的资源。
最先工作的线程如果是消费者,信号量mySem的值将会是0;如此线程被中断,直到生产者线程工作,生产资源,每生产一个资源mySem的值增加一,消费者才能使用资源,使用一个资源mySem减少一。此后生产者工作时会查看资源数组bufArray中的资源是否被使用,如果被使用则补充该资源。这样消费者与生产者之间的消费与生产活动就同步起来了。


相关问题
由于系统调度的缘故,可能程序的执行结果,在一段时间之内是一个生产者与 一个消费者不断的生产与消费,这在逻辑上也是成立的。

(yangqiang1989)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201009/10104.html]
本文出处:百度博客 作者:yangqiang1989
顶一下
(1)
50%
踩一下
(1)
50%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容