1. 条件变量介绍
条件变量是线程可用的一种同步机制,条件变量给多个线程提供了一个回合的场所,条件变量和互斥量一起使用,允许线程以无竞争的方式等待特定的条件发生。
条件变量本身是由互斥体保护的,线程在改变条件状态之前必须首先锁住互斥量,其他线程在获取互斥量之前就不会觉察到这种变化,因为互斥量必须锁定之后才改变条件。
条件变量总结:
- 条件变量要配合互斥锁使用。
- 条件变量支持单个唤醒和广播方式唤醒。
下面是视频监控的一个项目模型,摄像头的数据使用条件变量保护:
2. 条件变量相关接口函数
2.1 条件变量初始化与销毁
#include <pthread.h>
int pthread_cond_init(pthread_cond_t *restrict cond,const pthread_condattr_t *restrict attr);
用法示例示例:
pthread_cond_t cond;
pthread_cond_init(&cond, NULL);
int pthread_cond_destroy(pthread_cond_t *cond);
成功返回0,否则返回错误码
pthread_cond_init
用于初始化条件变量,最后使用完毕需要调用pthread_cond_destroy
销毁。
2.2 条件变量等待与唤醒
#include<pthread.h>
int pthread_cond_broadcast(pthread_cond_t *cond);
int pthread_cond_signal (pthread_cond_t *cond);
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
pthread_cond_broadcast
函数用于广播唤醒所有等待条件的休眠线程。
pthread_cond_signal
函数按顺序唤醒一个休眠的线程。
pthread_cond_wait
函数阻塞方式等待条件成立。第二个参数填互斥锁指针。
总结:
pthread_cond_signal函数一次性可以唤醒阻塞队列中的一个线程,pthread_cond_broadcast函数一次性可以唤醒阻塞队列中的所有线程。
3. 案例代码: 条件变量使用案例
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <signal.h>
pthread_cond_t cond;
pthread_mutex_t mutex;
/*
线程工作函数--消费者
*/
void *thread_work_func(void *dev)
{
int i=(int)dev;
printf("第%d个线程等待运行...\n",i);
//互斥锁上锁
pthread_mutex_lock(&mutex);
printf("互斥锁上锁成功.%d \n",i);
pthread_cond_wait(&cond,&mutex); //内部先解锁再加锁
pthread_mutex_unlock(&mutex);
printf("第%d个线程开始运行...\n",i);
}
//信号工作函数---生产者
void signal_work_func(int sig)
{
printf("正在唤醒休眠的线程.\n");
pthread_mutex_lock(&mutex);
pthread_cond_broadcast(&cond); //广播唤醒
//pthread_cond_signal (&cond); //唤醒单个休眠的线程
pthread_mutex_unlock(&mutex);
}
int main(int argc,char **argv)
{
//注册要捕获的信号
signal(SIGINT,signal_work_func);
//初始化条件变量
pthread_cond_init(&cond,NULL);
//初始化互斥锁
pthread_mutex_init(&mutex,NULL);
/*创建子线程*/
pthread_t thread_id;
int i;
for(i=0;i<10;i++)
{
if(pthread_create(&thread_id,NULL,thread_work_func,(void*)i)!=0)
{
printf("子线程%d创建失败.\n",i);
return -1;
}
//设置线程的分离属性
pthread_detach(thread_id);
sleep(1);
}
while(1)
{
}
//销毁条件变量
pthread_cond_destroy(&cond);
//销毁互斥锁
pthread_mutex_destroy(&mutex);
return 0;
}