博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
互斥锁和条件变量
阅读量:2384 次
发布时间:2019-05-10

本文共 2020 字,大约阅读时间需要 6 分钟。

 

信号量(semaphore)与已经介绍过的 IPC 结构不同,它是一个计数器。信号量用于实现进程间的互斥与同步,而不是用于存储进程间通信数据。

转载原文地址:

一直以来都理解错了,不是使用条件变量再加上一对互斥锁,而是条件变量内部引入一个互斥锁,其实主要还是条件变量在起作用,这样会提高效率,看下面的例子。

while(true){    pthread_mutex_lock(&mutex);    iCount++;    pthread_mutex_unlock(&mutex);}//thread 2:while(true){    pthread_mutex_lock(&mutex);    if(iCount >= 100)    {        iCount = 0;    }    pthread_mutex_unlock(&mutex);}

这种实现下,就算 lock 空闲,thread2需要不断重复<加锁,判断,解锁>这个流程,会给系统带来不必要的开销。有没有一种办法让 thread2先被 block,等条件满足的时候再唤醒 thread2?这样 thread2 就不用不断进行重复的加解锁操作了?(现在只是互斥,想要实现一个同步)这就要用到条件变量了:

//thread1 :while(true){    pthread_mutex_lock(&mutex);    iCount++;    pthread_mutex_unlock(&mutex);    pthread_mutex_lock(&mutex);    if(iCount >= 100)    {        pthread_cond_signal(&cond);    }    pthread_mutex_unlock(&mutex);}//thread2:while(1){    pthread_mutex_lock(&mutex);    while(iCount < 100)    {        pthread_cond_wait(&cond, &mutex);//这里的wait函数,在没有拿到信号之前,会一直处于阻塞等待的状态,不会像上一种情况不断的抢锁//在这种情况下,wait住了就不会去抢锁,这样避免了线程之间的切换    }    printf("iCount >= 100\r\n");    iCount = 0;    pthread_mutex_unlock(&mutex);}

需要注意的是,条件变量需要配合互斥锁来使用:

为什么要与pthread_mutex 一起使用呢? 这是为了应对 线程1在调用pthread_cond_wait()但线程1还没有进入wait cond的状态的时候,此时线程2调用了 cond_singal 的情况。 如果不用mutex锁的话,这个cond_singal就丢失了。如果等待时,条件不满足,那么就放锁,这样另一个线程就会拿到这个锁,继续运行,只有满足条件时,才会加锁。加了锁的情况是,线程2必须等到 mutex 被释放(也就是 pthread_cod_wait() 释放锁并进入wait_cond状态 ,此时线程2上锁) 的时候才能调用cond_singal.

简而言之就是,在thread 1 call pthread_cond_wait() 的时刻到 thread 1真正进入 wait 状态时,是存在着时间差的。如果在这段时间差内 thread2 调用了 pthread_cond_signal() 那这个 signal 信号就丢失了。给 wait 加锁可以防止同时有另一个线程在 signal。

 

使得效率变高是其一,

另外使用条件变量,避免了死锁的发生:

   以上是关于效率问题,此外互斥锁还有一个缺点就是会造成死锁。

   例如线程A和线程B都需要独占使用2个资源,但是他们都分别先占据了一个资源,然后又相互等待另外一个资源的释放,这样就形成了一个死锁。
条件变量起到了阻塞和唤醒线程的作用,所以通常互斥锁要和条件变量配合。
   为了解决以上问题,条件变量常和互斥锁一起使用,条件变量通过允许线程阻塞和等待另一个线程发送信号的方法弥补了互斥锁的不足。使用时,条件变量被用来阻塞一个线程,当条件不满足时,线程往往解开相应的互斥锁并等待条件发生变化。一旦其它的某个线程改变了条件变量,它将通知相应的条件变量唤醒一个或多个正被此条件变量阻塞的线程。这些线程将重新锁定互斥锁并重新测试条件是否满足。
---------------------
作者:似水流年0710
来源:CSDN
原文:https://blog.csdn.net/sishuiliunian0710/article/details/9625407
版权声明:本文为博主原创文章,转载请附上博文链接!

 

你可能感兴趣的文章
40岁的程序员找不到工作,原来码农真的是碗青春饭
查看>>
2018年前端性能优化总结,这也是我做程序员的第五个年头了
查看>>
前端进阶(三)从0到1学AJAX,这篇就够了!
查看>>
强大的CSS:实现平行四边形布局效果
查看>>
强大的CSS:滤镜和混合模式处理的图片如何上传下载?
查看>>
强大的CSS:var变量的局部作用域(继承)特性
查看>>
强大的CSS: 使用“变量种子计数器”扩展动画更多可能性
查看>>
强大的CSS:focus-visible伪类真的太6了!
查看>>
强大的CSS:3种姿势实现26个英文字母的案例
查看>>
强大的CSS:placeholder-shown伪类实现Material Design占位符交互效果
查看>>
强大的CSS:图形绘制合集,方便你我!
查看>>
强大的CSS:scroll-snap滚动事件停止及元素位置检测
查看>>
程序员30岁前,月薪达不到30K,该何去何从?
查看>>
只要记住这五点,学习任何新编程语言都不是问题
查看>>
常见的前端开发CSS 面试题及回答策略
查看>>
缺前端是假的,缺优秀前端是真的
查看>>
前端入门那么容易,工作很难找吗?
查看>>
Web前端很难学?html、css t、JavaScrip知识架构图分享
查看>>
常见的前端开发:Javascript 面试题及回答策略
查看>>
前端开发最容易出错的基础知识,面试常问!
查看>>