引言
本文为第十四篇,线程同步之条件变量 ,在上一篇文章是介绍了读写锁,读写锁在多读少写的情况下,性能要强于互斥量。本篇再介绍一种重要的处理线程同步的方法 — 条件变量
条件变量
- 条件变量是一种相对复杂的线程同步方法
- 条件变量允许线程睡眠,直到满足某种条件
- 当满足条件时,可以向该线程发送信号,通知唤醒线程
对于前边所介绍的生产者 - 消费者模型,其实是有一定的漏洞的
- 当缓冲区小于 0 时,不允许消费者消费,消费者必须等待
- 当缓冲区满时,不允许生产者往缓冲区生产,生产者必须等待
在前边的文章中并没有对这个进行约束,在本文学习条件变量时,将对这个进行更严谨的约束
假设此时缓冲区等于 0,当生产者生产一个产品时,唤醒可能等待的消费者 。假设缓冲区满时, 当消费者消费一个产品时,唤醒可能等待的生产者
条件变量的示例(需要配合互斥量来使用)
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
#include<vector>
#include<queue>
// 临界资源
int num=0;
// 缓冲区最大值
int MAX_BUF=100;
// 定义条件变量
pthread_cond_t cond=PTHREAD_COND_INITIALIZER;
// 定义互斥量
pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;
void* producer(void*){while(true){pthread_mutex_lock(&mutex);
while(num>=MAX_BUF){
// 等待
pthread_cond_wait(&cond, &mutex);
printf("缓冲区满了,等待消费者消费 \n");
}
num+=1;
printf("生产一个产品,当前产品数量为:%d", num);
sleep(1);// 生产产品所需时间
// 通知可能等待的消费者
pthread_cond_signal(&cond);
printf("通知消费者...\n");
// 解锁
pthread_mutex_unlock(&mutex);
sleep(1); 生产产品的频率
}
}
void* consumer(void*){while(true){pthread_mutex_lock(&mutex);
while(num<=0){
// 等待
pthread_cond_wait(&cond, &mutex);
printf("缓冲区空了,等待生产者生产 \n");
}
num-=1;
printf("消费一个产品,当前产品数量为:%d", num);
sleep(1);
// 通知可能等待的生产者
pthread_cond_signal(&cond);
printf("通知生产者...\n");
// 解锁
pthread_mutex_unlock(&mutex);
}
}
int main()
{
// 定义两个线程
pthread_t thread1,thread2;
// 一个执行生产者逻辑,一个执行消费者逻辑
pthread_create(&thread1, NULL, &producer, NULL);
pthread_create(&thread2, NULL, &consumer, NULL);
pthread_join(&thread1, NULL);
pthread_join(&thread2, NULL);
return 0;
}
执行结果:
在快速变化的技术中寻找不变,才是一个技术人的核心竞争力。知行合一,理论结合实践