Linux学习笔记10 条件变量

与互斥锁配合使用,可以达到如下效果——完成某个条件以后,指定线程才会继续执行。

生产者与消费者模型程序举例:生产者生产商品,消费者消费商品,如果没有商品了,消费者就要阻塞,等待商品生产出来。

主要函数如下:(注意其中的restrict关键词是告知编译器,所有修改该指针所指向内容的操作全部都是基于(base on)该指针的,即不存在其它进行修改操作的途径;这样的后果是帮助编译器进行更好的代码优化,生成更有效率的汇编代码。)

int pthread_cond_init(pyhread_cond_t *restrict cond, 
                      const pthread_condattr_t *restrict attr);
//条件变量初始化,第二个参数一般为NULL
 
int pthread_cond_destroy(pyhread_cond_t *cond);//摧毁条件变量标志

int pthread_cond_wait(pthread_cond_t *restrict cond, 
                      pthread_mutex_t *restrict mutex);
//等待条件触发,在这个时候会把互斥锁给释放掉,等到接受了条件再重新上锁
int pthread_cond_timedwait(pthread_cond_t *restrict cond, 
                           pthread_mutex_t *restrict mutex, 
                           const struct timespec *restrict abstime);
//在abstime时间内都会阻塞等待条件触发,但是时间到了,也没有触发条件,就会超时返回,解除阻塞。
int pthread_cond_signal(pthread_cond_t *cond); //发出条件信号,如果有等待的线程,可以接受
int pthread_cond_broadcast(pthread_cond_t *cond);//广播信号条件,所有的线程都会被唤醒

注意:这里重点理解一下pthread_cond_wait函数,它有两个入口参数,第一个很容易理解,就是条件变量的结构体,但是第二个是锁结构体,这个参数是为了告诉条件变量在阻塞等待时,应该释放哪个锁,然后解除条件变量时,应该加上哪个锁。

一般这个函数是在抢到锁以后再使用的,所以一般条件变量的使用流程是这样的:一个线程抢到了锁,但是线程需要满足一些条件才能继续运行,比如说消费者必须有产品才能消费,如果没有产品的情况下,就进入阻塞模式,并且把锁释放,留给其他线程去操作,等到某个其他线程,比如生产者生产了产品,并使用了pthread_cond_signal发出条件信号了,这个线程才解除阻塞,并且加锁以后继续运行。

都说需要锁和条件变量配合使用,为什么不能直接使用条件变量,是因为条件变量是线程的共享资源,也有可能发生线程的争抢情况。需要加锁实现线程安全。

#include <iostream>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>

using namespace std;
pthread_mutex_t mutex;//定义互斥锁变量
pthread_cond_t cond;//定义条件变量

struct list{
	int value;
	list* next;
};//创建一个链表作为商品

list *Head=NULL;
int num=0;
void *thr_product(void *arg)
{
	while (1){
		list *food= new list;
		food->value=num++;
		cout<<__FUNCTION__<<"---self="<<pthread_self()<<"---"<<food->value<<endl;
		pthread_mutex_lock(&mutex);
		food->next=Head;
		Head=food;
		pthread_mutex_unlock(&mutex);
		pthread_cond_signal(&cond);//解除在条件变量上的阻塞
		sleep(rand()%4);
	}
	return NULL;
}

void *thr_customer(void *arg)
{
	list *pro=NULL;
	while (1){
		pthread_mutex_lock(&mutex);
		if (Head==NULL) pthread_cond_wait(&cond, &mutex);
//在条件变量上阻塞,并且这条语句一定要与互斥锁配合使用,要先加锁
		pro=Head;
		Head=Head->next;
		cout<<__FUNCTION__<<"---self="<<pthread_self()<<"---"<<pro->value<<endl;
		pthread_mutex_unlock(&mutex);
		sleep(rand()%4);
		delete pro;
	}
	return NULL;
}

int main()
{
	pthread_mutex_init(&mutex, NULL); 
	pthread_cond_init(&cond, NULL);
	pthread_t tid[2];
	pthread_create(&tid[0], NULL, thr_product, NULL);
	pthread_create(&tid[1], NULL, thr_customer, NULL);
	pthread_join(tid[0],NULL);
	pthread_join(tid[1],NULL);
	pthread_mutex_destroy(&mutex);
	pthread_cond_destroy(&cond);
	return 0;
}

结果如图所示:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值