1.引入条件变量
配合互斥锁一起使用(不能单独使用),用来控制多个线程对于共享资源的访问。
当你使用互斥锁的时候,条件变量可以配合互斥锁实现满足某个条件的时候阻塞/解除阻塞某个线程。
比如:举的例子中某个条件是指票的数量<=0
条件变量有两个作用
作用一:条件变量可以阻塞线程
作用二:条件变量还可以唤醒(解除阻塞)线程
2.相关的接口函数
第一个:初始化条件变量
pthread_cond_t 表示条件变量
pthread_cond_t mycond;
int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr);
参数: cond --》你要使用的条件变量
cond_attr --》条件的属性,一般设置为NULL,表示使用默认属性
第二个:使用条件变量
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex); //阻塞线程
参数: cond --》你刚才定义初始化的那个条件变量
mutex --》你刚才定义的锁
注意重点:wait这个函数先解锁(做的第一件事情,防止死锁),然后在阻塞当前线程(做的第二件事情)
int pthread_cond_signal(pthread_cond_t *cond); //唤醒一个线程
参数:cond --》你刚才定义初始化的那个条件变量
注意重点:signal这个函数先上锁(做的第一件事情),然后在唤醒当前线程(做的第二件事情)
int pthread_cond_broadcast(pthread_cond_t *cond); //唤醒所有阻塞在wait上的线程
参数:cond --》你刚才定义初始化的那个条件变量
注意重点:broadcast这个函数先上锁(做的第一件事情),然后在唤醒所有的线程(做的第二件事情)
第三个:销毁条件变量
int pthread_cond_destroy(pthread_cond_t *cond)
多线程模拟售票,signal唤醒其中一个线程继续卖票
#include "myhead.h"
//定义全局变量表示当前放出来的票的数量
int num=15;
//定义锁变量
pthread_mutex_t mymutex;
//定义条件变量
pthread_cond_t mycond;
void *fun1(void *arg)
{
while(1)
{
pthread_mutex_lock(&mymutex);
if(num<=0) //阻塞当前线程
{
printf("窗口1阻塞在wait了!\n");
pthread_cond_wait(&mycond,&mymutex);
}
num--;
printf("窗口1卖出一张票,还剩下 %d 张票!\n",num);
sleep(1);
pthread_mutex_unlock(&mymutex);
usleep(100);
}
}
void *fun2(void *arg)
{
while(1)
{
pthread_mutex_lock(&mymutex);
if(num<=0) //阻塞当前线程
{
printf("窗口2阻塞在wait了!\n");
pthread_cond_wait(&mycond,&mymutex);
}
num--;
printf("窗口2卖出一张票,还剩下 %d 张票!\n",num);
sleep(1);
pthread_mutex_unlock(&mymutex);
usleep(100);
}
}
void *fun3(void *arg)
{
while(1)
{
pthread_mutex_lock(&mymutex);
if(num<=0) //阻塞当前线程
{
printf("窗口3阻塞在wait了!\n");
pthread_cond_wait(&mycond,&mymutex);
}
num--;
printf("窗口3卖出一张票,还剩下 %d 张票!\n",num);
sleep(1);
pthread_mutex_unlock(&mymutex);
usleep(100);
}
}
void *fun4(void *arg)
{
while(1)
{
pthread_mutex_lock(&mymutex);
if(num<=0) //阻塞当前线程
{
printf("窗口4阻塞在wait了!\n");
pthread_cond_wait(&mycond,&mymutex);
}
num--;
printf("窗口4卖出一张票,还剩下 %d 张票!\n",num);
sleep(1);
pthread_mutex_unlock(&mymutex);
usleep(100);
}
}
void *fun5(void *arg)
{
while(1)
{
pthread_mutex_lock(&mymutex);
if(num<=0) //阻塞当前线程
{
printf("窗口5阻塞在wait了!\n");
pthread_cond_wait(&mycond,&mymutex);
}
num--;
printf("窗口5卖出一张票,还剩下 %d 张票!\n",num);
sleep(1);
pthread_mutex_unlock(&mymutex);
usleep(100);
}
}
int main()
{
pthread_t id1,id2,id3,id4,id5;
//初始化锁
pthread_mutex_init(&mymutex,NULL);
//初始化条件变量
pthread_cond_init(&mycond,NULL);
//创建五个线程--》分别表示五个售票窗口
pthread_create(&id1,NULL,fun1,NULL);
pthread_create(&id2,NULL,fun2,NULL);
pthread_create(&id3,NULL,fun3,NULL);
pthread_create(&id4,NULL,fun4,NULL);
pthread_create(&id5,NULL,fun5,NULL);
//主函数代表铁道部,如果票卖完了,我从键盘输入数字表示新的票数
while(1)
{
if(num<=0)
{
printf("铁道部领导,票卖完了,请求放票出来!\n");
scanf("%d",&num);
//唤醒其中一个线程,让它来卖票
pthread_cond_signal(&mycond);
//唤醒所有的线程,一起来卖票
//pthread_cond_broadcast(&mycond);
}
}
//回收
pthread_join(id1,NULL);
pthread_join(id2,NULL);
pthread_join(id3,NULL);
pthread_join(id4,NULL);
pthread_join(id5,NULL);
}