线程条件变量的问题

DoDoMouse 2015-03-26 08:55:46
求助:
为什么在以下代码里面,消费者只能被激活一次?实在弄不懂...


#include <stdio.h>
#include <unistd.h>
#include <pthread.h>

pthread_cond_t tcon;
pthread_mutex_t tmut;
int i=0;

void* produce(void* arg)
{
int j=0;
for(j=0;j<10;j++)
{
pthread_mutex_lock(&tmut);

printf("producer begins work\n");
i++;
printf("in producer, i is %d\n",i);

pthread_mutex_unlock(&tmut);
pthread_cond_signal(&tcon);

sleep(1);
}
}

void* consume(void* arg)
{
printf("consumer thread is start\n");
int j=0;
for(j=0;j<5;j++)
{
pthread_cond_wait(&tcon,&tmut);
pthread_mutex_lock(&tmut);

printf("consumer begins work\n");
i--;
printf("in consumer, i is %d\n",i);

pthread_mutex_unlock(&tmut);
}
}

int main(int agc, char* argv[])
{
pthread_cond_init(&tcon,NULL);
pthread_mutex_init(&tmut,NULL);
pthread_cond_signal(&tcon);
pthread_t t1,t2,t3;
pthread_create(&t1,NULL,produce,NULL);
pthread_create(&t2,NULL,consume,NULL);
pthread_create(&t3,NULL,consume,NULL);
sleep(20);
printf("in main(), i is %d\n",i);
pthread_cond_destroy(&tcon);
pthread_mutex_destroy(&tmut);
}
...全文
132 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
DoDoMouse 2015-03-27
  • 打赏
  • 举报
回复
引用 2 楼 lincolnandlinda 的回复:
由于我没有mingw64的环境,用C++11提供的标准库把你的代码翻译了下,如下


#include <condition_variable>
#include <mutex>
#include <thread>
using namespace std;

mutex m;
condition_variable cv;
int cake_count = 0;
atomic<int> consumer_index = 0;

void produce()
{
	for (int i = 0; i < 10; i++)
	{
		{
			lock_guard<mutex> guard(m);
			printf("producer begins work \n");
			++cake_count;
		}
		cv.notify_one();
		this_thread::sleep_for(50ms);
	}
}

void consume()
{
	int index = ++consumer_index;
	printf("consumer thread %d begins \n", index);
	for (int i = 0; i < 5; i++)
	{
		unique_lock<mutex> locker(m);
		cv.wait(locker, []() {return cake_count > 0; });
		printf("consumer %d begins work \n", index);
		--cake_count;
		printf("consumer %d ends work \n", index);
		this_thread::sleep_for(10ms);
	}
}




int _tmain(int argc, _TCHAR* argv[])
{

	thread consumer1(consume);
	thread consumer2(consume);
	thread producer(produce);


	producer.join();
	consumer1.join();
	consumer2.join();
}
运行的结果如下 运行的结果没有什么问题。由于我是按照你的代码思路进行翻译的, 除了#1楼提出的问题外,我没看出来有什么其它问题。
谢谢回复,我的疑问已解决!
DoDoMouse 2015-03-27
  • 打赏
  • 举报
回复
引用 1 楼 hnwyllmm 的回复:
没仔细看,就看了这两句: pthread_cond_wait(&tcon,&tmut); pthread_mutex_lock(&tmut); 写反了,应该先加锁,再等待,等待的时候,会自动加上锁,当然如果是成功的话
感谢回复,确实是写反了。 我网上查看了下,对于pthread_cond_wait()这个函数,会先unlock mutex,然后进入等待状态。等到wait返回即条件满足的时候,再次lock mutext,并不是等待的时候加锁。
lincolnandlinda 2015-03-27
  • 打赏
  • 举报
回复
由于我没有mingw64的环境,用C++11提供的标准库把你的代码翻译了下,如下


#include <condition_variable>
#include <mutex>
#include <thread>
using namespace std;

mutex m;
condition_variable cv;
int cake_count = 0;
atomic<int> consumer_index = 0;

void produce()
{
for (int i = 0; i < 10; i++)
{
{
lock_guard<mutex> guard(m);
printf("producer begins work \n");
++cake_count;
}
cv.notify_one();
this_thread::sleep_for(50ms);
}
}

void consume()
{
int index = ++consumer_index;
printf("consumer thread %d begins \n", index);
for (int i = 0; i < 5; i++)
{
unique_lock<mutex> locker(m);
cv.wait(locker, []() {return cake_count > 0; });
printf("consumer %d begins work \n", index);
--cake_count;
printf("consumer %d ends work \n", index);
this_thread::sleep_for(10ms);
}
}




int _tmain(int argc, _TCHAR* argv[])
{

thread consumer1(consume);
thread consumer2(consume);
thread producer(produce);


producer.join();
consumer1.join();
consumer2.join();
}

运行的结果如下


运行的结果没有什么问题。由于我是按照你的代码思路进行翻译的, 除了#1楼提出的问题外,我没看出来有什么其它问题。
羽飞 2015-03-26
  • 打赏
  • 举报
回复
没仔细看,就看了这两句: pthread_cond_wait(&tcon,&tmut); pthread_mutex_lock(&tmut); 写反了,应该先加锁,再等待,等待的时候,会自动加上锁,当然如果是成功的话

64,639

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧