linux环境编程-线程同步【条件变量-生产者消费者】

一.条件变量

条件变量本身不是锁,但他可以造成线程阻塞,通常与互斥锁配合使用。给多线程提供一个会和场所

 

二.条件变量主要应用函数

  • int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr);
  • int pthread_cond_signal(pthread_cond_t *cond);
  • int pthread_cond_broadcast(pthread_cond_t *cond);
  • int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
  • int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime);
  • int pthread_cond_destroy(pthread_cond_t *cond);

以上6个函数成功都是返回0, 失败返回错误号。

pthread_cond_t 类型 定义条件变量如:pthread_cond_t cond;

 

要重点讲的就是这个 pthread_cond_wait

1.阻塞等待条件变量,cond

2.释放互斥锁,相当于 pthread_mutex_unlock(&mutex); 

1.2步是一个原子操作

3.当被唤醒,pthread_cond_wait返回,接触阻塞并重新申请获取互斥锁【pthread_mutex_lock(&mutex)】;

 

条件变量的优点

先比较与mutex而言,条件变量可以减少竞争

如果直接使用mutex,除了生产者,消费者之间要竞争互斥量意外,消费者之间也要竞争互斥量,但如果队列中没有数据,消费者之间竞争互斥锁是毫无意义的,有了条件变量机制之后,只有生产者完成了生产,才能引起消费者之间的竞争,提高了程序的执行效率。

 

三.生产者与消费者

原理图

#include <iostream>
#include <pthread.h>
#include <time.h>
#include <unistd.h>
#include <queue>
#include <iterator>


using namespace std;

#define THREAD_NUM 5
#define SHARE_MAX 3

// init
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t not_full = PTHREAD_COND_INITIALIZER;
pthread_cond_t has_prod = PTHREAD_COND_INITIALIZER;

queue<int> share; 

void*
prod_func(void* arg)
{
	int i = 10;
// int pthread_cond_timedwait(pthread_cond_t *cond,  pthread_mutex_t  *mutex,	
// const  struct  timespec *abstime);

	while(i--){
		pthread_mutex_lock(&mutex);
		while(share.size() == SHARE_MAX){
			pthread_cond_wait(&not_full, &mutex);			
		}
		share.push(rand()%10);
		printf("I am prod, the front val: %d the back val: %d\n", share.front(), share.back());
		printf("size: %lu \n", share.size());
		pthread_mutex_unlock(&mutex);
		pthread_cond_signal(&has_prod);
	}

	pthread_exit(NULL);
}

void*
cons_func(void* arg)
{
	int i = 10;
	while(i--){
		pthread_mutex_lock(&mutex);
		while(share.empty()){
			pthread_cond_wait(&has_prod, &mutex);			
		}
		share.pop();
		
		printf("I am cons, the front val: %d the back val: %d\n", share.front(), share.back());
		printf("size: %lu \n", share.size());
		pthread_mutex_unlock(&mutex);
		pthread_cond_signal(&not_full);
	}
	
	pthread_exit(NULL);
}

int
main(int argc, char*argv[])
{
	pthread_t prod_id, cons_id;
	srand(time(NULL));
	
	pthread_create(&prod_id, NULL, prod_func, NULL);
	pthread_create(&cons_id, NULL, cons_func, NULL);
	
	pthread_join(prod_id, NULL);
	pthread_join(cons_id, NULL);
	
	pthread_mutex_destroy(&mutex);
	pthread_cond_destroy(&has_prod);
	pthread_cond_destroy(&not_full);
	pthread_exit(NULL);
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值