线程同步2 ------ 条件变量实现“生产者-消费者”续
2017-12-06 18:09
169 查看
在上一篇转载博客的基础上,我想实现当生产者结束生产任务后,让消费者线程优雅主动地退出循环结束线程。具体代码修改如下。但是事与愿违,执行结果是,只有消费者线程里的第一个线程,能够主动退出循环结束线程,而其他消费者线程仍然不停地轮询等待。
代码:
运行结果:
问题不知道出在什么地方,留待以后慢慢改进。
代码:
#include <unistd.h> #include <sys/types.h> #include <pthread.h> #include <semaphore.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <sys/time.h> #define CONSUMERS_COUNT 5 #define PRODUCERS_COUNT 1 pthread_mutex_t mutex; pthread_cond_t cond; pthread_t g_thread[CONSUMERS_COUNT+PRODUCERS_COUNT]; int flag=1; //当生产者结束生产时,设置此标记为0,则消费者线程应该退出循环,结束线程 int product=0; //总共的需要生产和消费的产品数(任务) //消费者线程 void *consumer() { int ntotal=0; //记录本线程总共消费的产品数 while(1) { pthread_mutex_lock(&mutex); //任务数为0,且flag标记也被生产者设置为0,说明所有生产任务已经结束,消费者应该退出循环结束线程 if((product==0) && (flag==0)){ //原先没有以下语句。添加的目的是期望第一个或先退出的线程,发送一个唤醒信号, //让其他的消费者线程退出阻塞,有机会对是否应该退出线程进行检验 //现实是,此语句添加与否对执行结果无影响 pthread_cond_signal(&cond); pthread_mutex_unlock(&mutex); printf("Cons %u ended. Consumed %d pieces.\n\n",pthread_self(),ntotal); return NULL; //pthread_exit(0); } //当product为0时,消费者线程进入轮训,等待条件满足,然后伺机进行消费 while(product==0){ printf("%u waiting.\n\n",pthread_self()); pthread_cond_wait(&cond,&mutex); //也曾经尝试过使用pthread_cond_timedwait,唯一的区别,是除了第一个退出的消费者线程之外 //其他的消费者线程,每隔固定时间,仍然会继续轮训等待条件变量 } printf("%u consuming.\n\n",pthread_self()); product--; pthread_mutex_unlock(&mutex); sleep(1); ntotal++; } } //生产者线程 void *producer() { int nproduct=10; //总共需要生产和消费的产品数量 while(nproduct-->0){ pthread_mutex_lock(&mutex); printf("-- %u produce.\n",pthread_self()); product++; pthread_cond_signal(&cond); //发送信号唤醒消费者线程 pthread_mutex_unlock(&mutex); sleep(1); } //生产者线程完成所有生产任务,此时将flag标记为0, //期望此举可以让消费者线程明白,让所有消费者线程自行退出循环结束线程(但事与愿违,程序实际情况与此不符) //实际执行,只有第一个消费者线程能够主动退出循环结束线程运行,而后续的其他消费者线程继续轮询等待 pthread_mutex_lock(&mutex); flag=0; printf("-- %u exited. flag is set to %d\n",pthread_self(),flag); pthread_mutex_unlock(&mutex); return NULL; } main() { int i; pthread_mutex_init(&mutex,NULL); pthread_cond_init(&cond,NULL); for(i=0;i<CONSUMERS_COUNT;i++) pthread_create(&g_thread[i],NULL,consumer,(void *)i); sleep(1); for(i=0;i<PRODUCERS_COUNT;i++) pthread_create(&g_thread[CONSUMERS_COUNT+i],NULL,producer,(void *)i); for(i=0;i<CONSUMERS_COUNT+PRODUCERS_COUNT;i++) pthread_join(g_thread[i],NULL); pthread_mutex_destroy(&mutex); pthread_cond_destroy(&cond); printf("Main thread ends.\n"); }
运行结果:
问题不知道出在什么地方,留待以后慢慢改进。
相关文章推荐
- windows 使用关键段和条件变量实现的生产者和消费者线程同步
- 【Linux】线程总结:线程同步 -互斥锁,条件变量,信号量实现多生产者多消费者模型
- 线程同步2 ------ 用条件变量来解决生产者消费者问题
- ruby线程实现生产者消费者问题示例(队列Queue实现线程同步)
- 线程同步生产者和消费者c和java不同实现
- java实现线程同步一个生产者和一个消费者
- LinuxC/C++编程基础(8) 基于条件变量实现生产者与消费者的实例
- 多线程用互斥锁和条件变量实现生产者和消费者-------循环任务队列
- 使用Win32 API实现生产者消费者线程同步
- Linux--Condition Variable(条件变量)实现生产者-消费者模型 、读写锁
- Java 线程同步问题 生产者-消费者 算法实现 -Java学习笔记(29)
- 经典线程同步问题(生产者&消费者)--Java实现
- 利用条件变量实现多线程生产者消费者问题
- C#中生产者线程和消费者线程同步的实现
- 【线程同步2】java实现生产者消费者问题$扩展,出现的问题,思考
- 从java多线程实现“生产者-消费者”模型来谈谈操作系统中线程状态的转换及线程同步的总结
- 并发编程(一): POSIX 使用互斥量和条件变量实现生产者/消费者问题
- [线程同步]生产者消费者代码实现
- 并发编程(一): POSIX 使用互斥量和条件变量实现生产者/消费者问题
- linux 下 条件变量实现生产者消费者问题