一.条件变量
条件变量本身不是锁,但他可以造成线程阻塞,通常与互斥锁配合使用。给多线程提供一个会和场所
二.条件变量主要应用函数
- 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(¬_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(¬_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(¬_full);
pthread_exit(NULL);
}