注册网站查询系统,正规电商培训学校排名,招商网站建设网,郑州网站建设方案优化转自#xff1a;https://www.jb51.net/article/102764.htm
mutex体现的是一种竞争#xff0c;我离开了#xff0c;通知你进来。
cond体现的是一种协作#xff0c;我准备好了#xff0c;通知你开始吧。
互斥锁一个明显的缺点是它只有两种状态#xff1a;锁定和非锁定。…转自https://www.jb51.net/article/102764.htm
mutex体现的是一种竞争我离开了通知你进来。
cond体现的是一种协作我准备好了通知你开始吧。
互斥锁一个明显的缺点是它只有两种状态锁定和非锁定。而条件变量通过允许线程阻塞和等待另一个线程发送信号的方法弥补了互斥锁的不足它常和互斥锁一起配合使用。使用时条件变量被用来阻塞一个线程当条件不满足时线程往往解开相应的互斥锁并等待条件发生变化。一旦其他的某个线程改变了条件变量他将通知相应的条件变量唤醒一个或多个正被此条件变量阻塞的线程。这些线程将重新锁定互斥锁并重新测试条件是否满足。一般说来条件变量被用来进行线程间的同步。
两个线程操作同一临界区时通过互斥锁保护若A线程已经加锁B线程再加锁时候会被阻塞直到A释放锁B再获得锁运行进程B必须不停的主动获得锁、检查条件、释放锁、再获得锁、再检查、再释放一直到满足运行的条件的时候才可以而此过程中其他线程一直在等待该线程的结束这种方式是比较消耗系统的资源的。而条件变量同样是阻塞还需要通知才能唤醒线程被唤醒后它将重新检查判断条件是否满足如果还不满足该线程就休眠了应该仍阻塞在这里等待条件满足后被唤醒节省了线程不断运行浪费的资源。这个过程一般用while语句实现。当线程B发现被锁定的变量不满足条件时会自动的释放锁并把自身置于等待状态让出CPU的控制权给其它线程。其它线程 此时就有机会去进行操作当修改完成后再通知那些由于条件不满足而陷入等待状态的线程。这是一种通知模型的同步方式大大的节省了CPU的计算资源减少了线程之间的竞争而且提高了线程之间的系统工作的效率。这种同步方式就是条件变量。
以上说明可能有点抽象考虑这样的简单场景通过伪代码说明。
A线程从队列中取元素B线程往队列中存放元素。不考虑免锁的实现。需要一个mutex用来保护队列的一致性避免两个线程同时操作队列破坏数据结构。
当队列为空的时候A需要不断的探测队列状态 :
? 1 2 3 4 5 6 7 8 9 10 11 while(1) { if(队列为空) 休眠10s else { 加锁 取元素 解锁 } } 这就有一个问题可能在刚进入休眠时B放入元素了但仍然需要休眠完整个10s的时间。造成不必要的延迟。当然如果不sleep也可以但会造成不必要的CPU开销。使用基于条件变量的事件通知唤醒机制就可以避免这些问题。
一旦B放入元素完成后就执行pthread_cond_signal()当前阻塞的线程就会立即被唤醒开始干活儿。
? 1 2 3 4 5 6 while(1) { pthread_mutex_lock(); pthread_cond_wait(); 取元素 pthread_mutex_unlock(); } 条件变量都用互斥锁进行保护条件变量状态的改变都应该先锁住互斥锁pthread_cond_wait()需要传入一个已经加锁的互斥锁该函数把调用线程加入等待条件的调用列表中然后释放互斥锁在条件满足从而离开pthread_cond_wait()时mutex将被重新加锁这两个函数是原子操作。
可以消除条件发生和线程睡眠等待条件发生间的时间间隙。其他线程在获得互斥量之前不会察觉到这种改变因为必须锁定互斥量才能计算条件。
总而言之为了避免因条件判断语句与其后的正文或wait语句之间的间隙而产生的漏判或误判所以用一个mutex来保证: 对于某个cond的包括(判断,修改)在内的任何有关操作某一时刻只有一个线程在访问。也就是说条件变量本身就是一个竞争资源这个资源的作用是对其后程序正文的执行权于是用一个锁来保护。
这样就关闭了条件检查和线程进入休眠状态等待条件改变这两个操作之间的时间通道这样线程就不会有任何变化。
感觉可以总结为条件变量用于某个线程需要在某种条件成立时才去保护它将要操作的临界区这种情况从而避免了线程不断轮询检查该条件是否成立而降低效率的情况这是实现了效率提高。。。在条件满足时自动退出阻塞再加锁进行操作。
以上是关于效率问题此外互斥锁还有一个缺点就是会造成死锁。
例如线程A和线程B都需要独占使用2个资源但是他们都分别先占据了一个资源然后又相互等待另外一个资源的释放这样就形成了一个死锁。
条件变量起到了阻塞和唤醒线程的作用所以通常互斥锁要和条件变量配合。
为了解决以上问题条件变量常和互斥锁一起使用条件变量通过允许线程阻塞和等待另一个线程发送信号的方法弥补了互斥锁的不足。使用时条件变量被用来阻塞一个线程当条件不满足时线程往往解开相应的互斥锁并等待条件发生变化。一旦其它的某个线程改变了条件变量它将通知相应的条件变量唤醒一个或多个正被此条件变量阻塞的线程。这些线程将重新锁定互斥锁并重新测试条件是否满足。
以上就是小编为大家带来的浅谈互斥锁为什么还要和条件变量配合使用全部内容了希望大家多多支持脚本之家~