条件变量
条件变量必须与互斥锁一起连用,条件变量中的线程不会主动醒来,而是要等待别的线程唤醒条件变量。
条件变量的函数接口
1)初始化一个条件变量
pthread_cond_init()
动态初始化:
ond:未初始化的条件变量的地址 pthread_cond_t 条件变量的地址类型
attr:属性 普通属性NULL
失败返回错误码
静态初始化: pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
2)进入条件变量中进行等待
pthread_cond_wait()
如果满足进入条件变量中等待,则进入之前默认自动解锁。
cond: 已经初始化过的条件变量
mutex:已经在上锁状态的互斥锁的地址
失败返回错误码
3)唤醒条件变量中的等待的线程
广播: 唤醒条件变量中所有的线程 pthread_cond_broadcast()
单播: 随机唤醒条件变量中的一个线程 pthread_cond_signal()
cond: 已经初始化的条件变量
失败返回错误码
4)销毁条件变量
pthread_cond_destroy()
cond: 已经初始化的条件变量
失败返回错误码
pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t v = PTHREAD_COND_INITIALIZER;
int sum = 400;
//线程任务:-200
void *routine(void *arg)
{
//在访问之前,首先要先上锁
pthread_mutex_lock(&m);
while(sum < 200) //这里不能使用if,因为醒来之后还需要判断sum是否小于200
{
//则进入条件变量中等待
pthread_cond_wait(&v,&m); //自动解锁,进入条件变量v中睡觉!
}
//从循环出来: 一定是被唤醒并且是>=200
printf("before money:%d\n",sum);
sum -= 200;
printf("after money:%d\n",sum);
pthread_mutex_unlock(&m); //解锁
pthread_exit(NULL);//结束
}
void *time_fun(void *arg)
{
int i = 0;
while(1)
{
printf("%d\n",i++);
sleep(1);
}
}
int main()
{
pthread_t tid_test;
pthread_create(&tid_test,NULL,time_fun,NULL);
pthread_t tid[5]; //存放5个子线程的ID 下标:0~4
int i;
for(i=0;i<5;i++)
{
pthread_create(&tid[i],NULL,routine,NULL);
}
sleep(3); //2个运行,3个在睡觉
pthread_mutex_lock(&m);
sum += 200;
printf("parent + 200!\n");
pthread_mutex_unlock(&m);
sleep(5);
pthread_cond_broadcast(&v);// 唤醒条件变量中3个正在睡觉的
printf("broadcast!\n");
sleep(2);
pthread_mutex_lock(&m);
sum += 400;
printf("parent + 400!\n");
pthread_mutex_unlock(&m);
pthread_cond_signal(&v);
printf("signal!\n");
sleep(5);
pthread_cond_signal(&v);
printf("signal!\n");
for(i=0;i<5;i++)
{
pthread_join(tid[i],NULL);
}
pthread_mutex_destroy(&m);
pthread_cond_destroy(&v);
return 0;
}