线程安全--条件变量实现,互斥锁与条件变量搭配使用实现线程安全,厨师与顾客

//线程安全概念在前一篇文章线程安全–互斥锁实现已经讲过,这个直接从如何实现开始。
互斥锁的互斥 实现线程安全
条件变量的同步 实现线程安全

通过一个条件变量判断是否满足获取资源的条件。满足,则获取资源,不满足,则等待。

在条件变量实现线程安全中,只提供两个接口+等待队列:让执行流等待接口和唤醒执行流接口+两个pcb等待队列(所以有两个条件变量)

所以对于程序中什么时候线程等待,什么时候线程唤醒由程序员在进程中进行判断。

不像互斥锁实现安全的过程,程序员只需要考虑加锁解锁将共享资源保护住就可以,其他的都是线程自己完成。线程过来加锁,mutex=0表示锁了,线程自动阻塞,mutex=1时,线程自动加锁。
1、定义条件变量
pthread_cond_t cond;
2、初始化条件变量
pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *attr);动态分配
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;静态分配
pthread_cond_init(&cond,NULL);
3、若资源获取条件不够,则调用接口进行阻塞等待。
pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);—一直等待
pthread_cond_timewait(pthread_cond_t *, pthread_mutex_t ,struct timespec ) ;—设置的时间等待接口-如果时间到了没有被唤醒会自动醒来。
pthread_cond_wait(&cond,&mutex);
等待的函数为什么要加参数互斥锁
(条件变量实现同步的时候,互斥锁在共享资源访问/结束时也要用,再就是在这个wait函数中搭配条件变量使用)

条件等待是同步的一种手段,但是当条件不满足时,线程会一直等待,所以我们需要改变一些共享变量,使不满足的条件变得满足。对于共享数据的变化,我们是必须使用互斥锁来保护的。
在这里插入图片描述
当我们保护了共享资源之后,当条件满足,我们就操作共享资源改变条件,但是当条件不满足的时候,线程是需要等待的,这个时候,对共享资源是应该解锁的,然后让线程等待,但是解锁和线程等待都不是原子操作,若这个线程刚刚解锁,其他线程就获得了互斥量进行加锁,这个线程又没有阻塞等待,可能导致这个线程永远阻塞了。所以解锁与等待和被唤醒后加锁必须是原子操作。
4、唤醒线程的接口
pthread_cond_signal(pthread_cont_t *)— 唤醒至少一个等待的线程(并不是唤醒单个)
pthread_cond_broadcast(pthread_cond_t *)—唤醒所有等待的线程
pthread_cond_signal(&cond);
5、销毁条件变量
pthread_cond_destory(pthread_cond_t *)
pthread_cond_destroy(&cond);

同步实现线程安全的流程图
在这里插入图片描述
上图的第二步里边一定要是个原子操作的,所以就有了pthread_cond_wait(cond,mutex)要条件变量搭配互斥使用。
流程图文字说明
1,当我们去进行条件判断之前,我们需要先对条件变量进行加锁 —mutex_lock
2.访问条件变量,判断
条件变量不满足,等待前先解锁(mutex_unlock)
等待 cond_wait
突然被唤醒,加锁(mutex_lock)
3.条件变量满足,则继续实现
4,实现完了。则唤醒另一个进程cond_signal
5.解锁 mutex_unlock

注意:
2那块的那三步应该是原子操作,所以有pthread_cond_wait(cond,mutex)条件变量与互斥锁搭配使用。

等待条件的代码

pthread_mutex_lock(&mutex);
 while (条件为假)
 pthread_cond_wait(cond, mutex);
 修改条件
 pthreamutex_unlock(&mutex);

给条件发送信号代码

pth
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值