您的位置:首页 > 编程语言 > C语言/C++

线程同步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");
}


运行结果:



      问题不知道出在什么地方,留待以后慢慢改进。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐