免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3152 | 回复: 2
打印 上一主题 下一主题

问一下pthread条件变量的问题(已解决) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-11-05 18:14 |只看该作者 |倒序浏览
本帖最后由 izualzhy 于 2011-11-07 16:02 编辑

例子代码主要实现producer线程生产(添加元素到链表),consumer线程消费(取出元素从链表)。按理说是LIFO才对,不过执行多次程序时有时会出现不符合LIFO的情况(都是在刚开始时出现)。
我仔细检查了下代码,应该是对的。与signal的位置没有关系。
结果有时是这样的:
Produce 160
Produce 93
Consume 160

谢谢!
  1. #include <stdlib.h>
  2. #include <pthread.h>
  3. #include <stdio.h>

  4. struct msg {
  5.         struct msg *next;
  6.         int num;
  7. };

  8. volatile struct msg *head;
  9. pthread_cond_t hasProduct = PTHREAD_COND_INITIALIZER;
  10. pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

  11. void *consumer(void *p)
  12. {
  13.         struct msg *mp;
  14.         for(;;) {
  15.                 /*printf("consumer before lock......\n");*/
  16.                 pthread_mutex_lock(&lock);
  17.                 /*printf("consumer get locked : 0x%x\n",head);*/
  18.                 while (head==NULL) {
  19.                 /*if (head==NULL) {*/
  20.                 //条件受互斥锁保护?
  21.                 //用while不用if?
  22.                         printf("consumer entering wait......\n");
  23.                         pthread_cond_wait(&hasProduct,&lock);
  24.                         printf("consumer leaveing wait : %d......\n",head->num);
  25.                 }
  26.                 mp = head;
  27.                 head = mp->next;
  28.                 pthread_mutex_unlock(&lock);
  29.                 printf("Consume %d\n",mp->num);
  30.                 /*printf("Consume 0x%x,%d,0x%x\n", mp,mp->num,head);*/
  31.                 free(mp);
  32.                 sleep(rand()%5);
  33.         }
  34. }

  35. void *producer(void *p)
  36. {
  37.         /*printf("producer starting......\n");*/
  38.         struct msg *mp;
  39.         for(;;) {
  40.                 mp = malloc(sizeof(struct msg));
  41.                 mp->num = rand()%1000 + 1;
  42.                 /*printf("producer before lock......\n");*/
  43.                 pthread_mutex_lock(&lock);
  44.                 mp->next = head;
  45.                 head = mp;
  46.                 printf("Produce %d\n",mp->num);
  47.                 pthread_mutex_unlock(&lock);
  48.                 /*printf("producer before signal......\n");*/
  49.                 pthread_cond_signal(&hasProduct);
  50.                 //signal与lock位置无关
  51.                 sleep(rand()%5);
  52.         }
  53. }

  54. int main(int argc, char *argv[])
  55. {
  56.         pthread_t pid,cid;
  57.         srand(time(NULL));
  58.         pthread_create(&pid,NULL, producer, NULL);
  59.         pthread_create(&cid,NULL, consumer, NULL);

  60.         pthread_join(pid,NULL);
  61.         pthread_join(cid,NULL);

  62.         struct msg* mp = head;
  63.         while (head!=NULL) {
  64.                 mp = head;
  65.                 head = head->next;
  66.                 printf("main thread: %d\n",mp->num);
  67.                 free(mp);
  68.         }
  69.         return 0;
  70. }
复制代码

论坛徽章:
0
2 [报告]
发表于 2011-11-07 15:09 |只看该作者
本帖最后由 digdeep126 于 2011-11-07 15:11 编辑

回复 1# izualzhy


    很简单,你将 pthread_mutex_unlock(&lock);和printf("Consume %d\n",mp->num);两者的位置条换一下就不会出现这样的问题了。
出现你所说的原因是:消费者的打印语句printf("Consume %d\n",mp->num);因为没有在锁中,所以消费第一个“产品”的打印语句是可能发生在第二个“产品”已经产生的后面的。但这是并不与“LIFO”相矛盾!

论坛徽章:
0
3 [报告]
发表于 2011-11-07 16:02 |只看该作者
回复 2# digdeep126


    看了下的确是,只顾去关注互斥量啊什么的位置了,谢谢。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP