`
M_ittrue
  • 浏览: 75222 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

Condition Variable与Mutex搭配的前因后果

阅读更多

本来打算用一个形象的生活情况来比喻条件互斥的,但想了再想实在没有想到比较科学贴切的比喻.

那还是开门见山来说吧.

Condition Variable无论在C/C++还是C#,JAVA语言里,都会搭配一个Mutex来用.

我们知道Mutex的普通意义上是维持一个互斥变量,从而保证一个或一组操作的原子性.

同样,简单的说Mutex加在Condition Variable上也是为了保证它的原子性了.

Condition Variable,有条件的唤醒机制.最经典不过的就是生产--消息者模型了.

但有一个细节,消费者需要有"产品"才能继续它的消费行为,因此当消费者发现"产品"

被消费完了?它该怎么办?

没错,普通情况下它就会进入等待挂起状态.但这一状态什么时候才能结束?又是谁来告诉它

有"产品"可消费呢?没错,这个时候消费者就是在等待"有产品可消费"这一条件才会苏醒.

 

这个时候我们就能用到Condition Variable了.

上代码:#include <stdio.h>

#include <stdlib.h>
#include <pthread.h>
struct msg{
	struct msg *next;
	int num;
};

struct msg *head;
pthread_cond_t has_product;//Condition Variable
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;//互斥锁初始化

void *consumer(void *p)
{
	struct msg *mp;
	for(;;){
		pthread_mutex_lock(&lock);//保证生产与消费的互斥,消费者取得lock
		while(head == NULL)
			pthread_cond_wait(&has_product,&lock);

 //其实while这一过程并不是必需的,  pthread_cond_wait这一过程已经可以实现等待-执行可程了.但由于线程被唤醒的情况有多种,我们需要的是head!=NULL这种情况才会继续执行.而且pthread_cond_wait()这个方法还会有一个内在的执行过程,在pthread_cond_wait()这一过程中我们必需保证lock的持有,当线程刷新了等待队列之后,在被持起之前lock会被释放.

当另一个线程调用pthread_cond_signal()唤醒之前需要先把lock给释放了,因为调用pthread_cond_signal()后,消费进程需要重新通过pthread_cond_wait()这个方法获得lock,然后执行逻辑处理代码,最后消费进程释放lock.

 

		mp = head;
		head = mp->next;
		pthread_mutex_unlock(&lock);//释放lock
		printf("Consumer %d\n",mp->num);
		free(mp);
		sleep(rand()%5);
	}
}

void *producer(void *p)
{
	struct msg *mp;
	for(;;){
		mp = malloc(sizeof(struct msg));
		mp->num = rand() % 1000+1;
		printf("Produce %d\n",mp->num);
		pthread_mutex_lock(&lock);//为保证操作的原子性获得lock
		mp->next = head;
		head = mp;
		pthread_mutex_unlock(&lock);//释放lock
		pthread_cond_signal(&has_product);//唤醒消费进程
		sleep(rand()%5);

	}
}

int main(int argc,char *argv[])
{
	pthread_t pid,cid;
	srand(time(NULL));
	cid = pthread_create(&cid,NULL,consumer,NULL);
	pid = pthread_create(&pid,NULL,producer,NULL);
	sleep(5);
	pthread_join(pid,NULL);
	pthread_join(cid,NULL);
	return 0;
}

 

上面文字解释是关键部份,主要是pthread_cond_wait()这一内在执行过程比较重要.

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics