Chinaunix首页 | 论坛 | 博客
  • 博客访问: 484023
  • 博文数量: 120
  • 博客积分: 1853
  • 博客等级: 上尉
  • 技术积分: 1177
  • 用 户 组: 普通用户
  • 注册时间: 2011-10-22 22:40
文章分类

全部博文(120)

文章存档

2013年(16)

2012年(104)

分类: LINUX

2013-09-30 21:20:28


1.pthread_cond_wait()会干两件事
a).阻塞本线程
b).释放锁,等待singal或者broadcast,条件变量改变之后,加锁。唤醒线程
以上a+b是一个原子操作
2.既然wait已经释放锁了,那么如果signal在加解锁mutex中间的话,会一直等到释放锁了,wait才能得到条件变量修改的信息。
也就是说wait不仅等signal或broadcast,也会等pthread_mutex_unlock。只有两个条件都满足了才会继续执行
3.本例子中的singal是放在加解锁之间的,这样也不会损失性能(对linux是这样),而不会出现race condition,否则放在mutex unlock之后,可能会有别的线程抢占mutex
4.本例子中,0= 5.在consume和produce函数中,每次加/减完毕都会signal

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <pthread.h>
  3. #include <iostream>
  4. using namespace std;
  5. pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
  6. pthread_cond_t event = PTHREAD_COND_INITIALIZER;

  7. int num = 0;
  8. int countP = 0;

  9. bool flag=false;

  10. void *produce(void *p)
  11. {
  12.     int count = 0;
  13.     while(!flag)    
  14.     {
  15.         pthread_mutex_lock(&lock);
  16.         while(num==100)
  17.         {
  18.             pthread_cond_wait(&event,&lock);
  19.         }
  20.         num++;
  21.         pthread_cond_signal(&event);
  22.         pthread_mutex_unlock(&lock);
  23.         count++;
  24.     }
  25.     return (void*)count;
  26. }

  27. void *cosume(void *p)
  28. {
  29.     int count = 0;
  30.     while(!flag)
  31.     {
  32.         pthread_mutex_lock(&lock);
  33.         while(num==0)
  34.         {    
  35.             pthread_cond_wait(&event, &lock);
  36.         }
  37.         num--;
  38.         countP++;
  39.         if(countP==100000)
  40.             flag = true;
  41.         pthread_cond_signal(&event);
  42.         pthread_mutex_unlock(&lock);
  43.         count++;
  44.     }
  45.     return (void*)count;
  46. }

  47. int main()
  48. {
  49.     pthread_t tid[4];
  50.     pthread_create(tid+0, NULL, produce, NULL);
  51.     pthread_create(tid+1, NULL, produce, NULL);
  52.     pthread_create(tid+2, NULL, cosume, NULL);
  53.     pthread_create(tid+3, NULL, cosume, NULL);
  54.     
  55.     int countP;
  56.     int countM;
  57.     pthread_join(tid[0], (void**)&countM);
  58.     cout<<"producer 0 "<<" "<<countM<<endl;
  59.     pthread_join(tid[1], (void**)&countM);
  60.     cout<<"producer 1 "<<" "<<countM<<endl;
  61.     pthread_join(tid[2], (void**)&countM);
  62.     cout<<"consumer 0 "<<" "<<countM<<endl;
  63.     pthread_join(tid[3], (void**)&countM);
  64.     cout<<"consumer 1 "<<" "<<countM<<endl;
  65.         

  66.     return 0;
  67. }
以下是对上面的另一个实现版本,改动如下:
1.不是每次都signal,而是有判断,才signal;
2.其实1中的signal我都改为了broadcast;
3.为了符合每次循环只有一次对num的操作,添加了两个bool变量
其中使用了broadcast,不知道为什么使用signal不可。不过unp上的一段话可以作为参看。
考虑条件信号量单播发送和广播发送的一种候选(且更为安全的)方式市坚持使用广播发送。如果所有的等待者代码都编写确切,只有一个等待者需要唤醒,而且唤醒哪一个无关紧要,那么可以使用为这些情况而优化的单播。所有其他情况都应該使用广播发送。



点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <pthread.h>
  3. #include <iostream>
  4. using namespace std;
  5. pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
  6. pthread_cond_t event = PTHREAD_COND_INITIALIZER;

  7. int num = 0;
  8. int countP = 0;

  9. bool flag=false;

  10. void *produce(void *p)
  11. {
  12.     int count = 0;
  13.     while(!flag)
  14.     {
  15.         pthread_mutex_lock(&lock);
  16.         while(num==100)
  17.         {
  18.             cout<<"producer num==100"<<endl;
  19.             pthread_cond_wait(&event,&lock);
  20.         }

  21.         bool empty = false;
  22.         if(num==0)
  23.         {
  24.             empty=true;
  25.             num++;
  26.             cout<<"producer num==0"<<endl;
  27.             pthread_cond_broadcast(&event);
  28.         }
  29.         if(!empty)
  30.             num++;
  31.         pthread_mutex_unlock(&lock);
  32.         count++;
  33.     }
  34.     return (void*)count;
  35. }

  36. void *cosume(void *p)
  37. {
  38.     int count = 0;
  39.     while(!flag)
  40.     {
  41.         pthread_mutex_lock(&lock);
  42.         while(num==0)
  43.         {
  44.             cout<<"consume num==0"<<endl;
  45.             pthread_cond_wait(&event, &lock);
  46.         }
  47.         countP++;
  48.         if(countP==1000)
  49.             flag = true;
  50.         bool full = false;
  51.         if(num==100)
  52.         {
  53.             full = true;
  54.             num--;
  55.             cout<<"consume num==100"<<endl;
  56.      pthread_cond_broadcast(&event);
  57.         }
  58.         if(!full)
  59.             num--;
  60.         pthread_mutex_unlock(&lock);
  61.         count++;
  62.     }
  63.     return (void*)count;
  64. }

  65. int main()
  66. {
  67.     pthread_t tid[4];
  68.     pthread_create(tid+0, NULL, produce, NULL);
  69.     sleep(1);
  70.     pthread_create(tid+1, NULL, produce, NULL);
  71.     sleep(1);
  72.     pthread_create(tid+2, NULL, cosume, NULL);
  73.     pthread_create(tid+3, NULL, cosume, NULL);
  74.     
  75.     int countP;
  76.     int countM;
  77.     pthread_join(tid[0], (void**)&countM);
  78.     cout<<"producer 0 "<<" "<<countM<<endl;
  79.     pthread_join(tid[1], (void**)&countM);
  80.     cout<<"producer 1 "<<" "<<countM<<endl;
  81.     pthread_join(tid[2], (void**)&countM);
  82.     cout<<"consumer 0 "<<" "<<countM<<endl;
  83.     pthread_join(tid[3], (void**)&countM);
  84.     cout<<"consumer 1 "<<" "<<countM<<endl;
  85.         

  86.     return 0;
  87. }



阅读(3572) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~