免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 36433 | 回复: 11
打印 上一主题 下一主题

[C] 互斥锁和信号量的区别 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-08-28 09:03 |只看该作者 |倒序浏览
ipc中的信号量和多线程中的互斥锁都是同步机制,我觉得二者可以互换使用,大家有什么看法

论坛徽章:
0
2 [报告]
发表于 2008-08-28 09:12 |只看该作者
个人认为看使用的场合:

信号量用在多线程多任务同步的,一个线程完成了某一个动作就通过信号量告诉别的线程,别的线程再进行某些动作(大家都在semtake的时候,就阻塞在哪里)。

而互斥锁是用在多线程多任务互斥的,一个线程占用了某一个资源,那么别的线程就无法访问,直到这个线程unlock,其他的线程才开始可以利用这个资源。比如对全局变量的访问,有时要加锁,操作完了,在解锁。

有的时候锁和信号量会同时使用的。我记得以前做的一个项目就是既有semtake,又有lock。不知道说的对不对。

[ 本帖最后由 nicozhou 于 2008-8-28 10:22 编辑 ]

论坛徽章:
0
3 [报告]
发表于 2008-08-28 10:07 |只看该作者
这是概念上的区别,   
  比如说,信号,那是多线程同步用的,一个线程完成了某一个动作就通过信号告诉别的线程,别的线程再进行某些动作。   
  互斥锁,这是多线程互斥用的,比如说,一个线程占用了某一个资源,那么别的线程就无法访问,知道这个线程离开,其他的线程才开始可以利用这个资源。

论坛徽章:
0
4 [报告]
发表于 2008-08-28 10:23 |只看该作者
我的理解:mutex只有两个状态,而semaphore不只。

另外,从实现上来讲,posix semaphore比较容易用于进程间通信。而posix mutex好像主要用于进程内部(线程间)。

[ 本帖最后由 lgfang 于 2008-8-28 10:32 编辑 ]

论坛徽章:
0
5 [报告]
发表于 2008-08-28 10:56 |只看该作者

回复 #4 lgfang 的帖子

明白了,semaphore也可以用于线程间共享资源的保护,但mutex却不能用于进程间共享资源的保护,因为两个进程不可能共用一个mutex

论坛徽章:
0
6 [报告]
发表于 2008-08-28 11:01 |只看该作者
2值信号量就是互持锁的功能了.
而多值的信号量用在类似于"生产者消费者"这样的应用中.

论坛徽章:
0
7 [报告]
发表于 2008-08-28 11:05 |只看该作者
原帖由 wangxiaoguang 于 2008-8-28 10:56 发表
明白了,semaphore也可以用于线程间共享资源的保护,但mutex却不能用于进程间共享资源的保护,因为两个进程不可能共用一个mutex


这只是一方面。
另一个区别也是很重要的。

论坛徽章:
0
8 [报告]
发表于 2010-10-08 17:31 |只看该作者
回复 1# wangxiaoguang
下面是我在别的地方看到的关于这方面的知识,转来给大家分享下。希望能帮到大家。


信号量mutex是sleep-waiting。 就是说当没有获得mutex时,会有上下文切换,将自己、加到忙等待队列中,直到另外一个线程释放mutex并唤醒它,而这时CPU是空闲的,可以调度别的任务处理。

而spin lock是busy-waiting。就是说当没有可用的锁时,就一直忙等待并不停的进行锁请求,直到得到这个锁为止。这个过程中cpu始终处于忙状态,不能做别的任务。

例如在一个双核的机器上有两个线程(线程A和线程B),它们分别运行在Core0 和Core1上。 用spin-lock,coer0上的线程就会始终占用CPU。
另外一个值得注意的细节是spin lock耗费了更多的user time。这就是因为两个线程分别运行在两个核上,大部分时间只有一个线程能拿到锁,所以另一个线程就一直在它运行的core上进行忙等待,CPU占用率一直是100%;而mutex则不同,当对锁的请求失败后上下文切换就会发生,这样就能空出一个核来进行别的运算任务了。(其实这种上下文切换对已经拿着锁的那个线程性能也是有影响的,因为当该线程释放该锁时它需要通知操作系统去唤醒那些被阻塞的线程,这也是额外的开销)

总结
(1)Mutex适合对锁操作非常频繁的场景,并且具有更好的适应性。尽管相比spin lock它会花费更多的开销(主要是上下文切换),但是它能适合实际开发中复杂的应用场景,在保证一定性能的前提下提供更大的灵活度。

(2)spin lock的lock/unlock性能更好(花费更少的cpu指令),但是它只适应用于临界区运行时间很短的场景。而在实际软件开发中,除非程序员对自己的程序的锁操作行为非常的了解,否则使用spin lock不是一个好主意(通常一个多线程程序中对锁的操作有数以万次,如果失败的锁操作(contended lock requests)过多的话就会浪费很多的时间进行空等待)。

(3)更保险的方法或许是先(保守的)使用 Mutex,然后如果对性能还有进一步的需求,可以尝试使用spin lock进行调优。毕竟我们的程序不像Linux kernel那样对性能需求那么高(Linux Kernel最常用的锁操作是spin lock和rw lock)。

论坛徽章:
1
丑牛
日期:2013-09-29 19:04:50
9 [报告]
发表于 2013-04-30 11:19 |只看该作者
qliu00 发表于 2008-08-28 10:07
这是概念上的区别,   
比如说,一个线程占用了某一个资源,那么别的线程就无法访问,知道这个线程离开,其他的线程才开始可以利用这个资源。



这种说法不对吧。 就算你占用了,别人也是可以访问并使用的。 只不过,,,,

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
10 [报告]
发表于 2013-04-30 11:53 |只看该作者
也有进程间的mutex。。。。

semaphore为什么不能代替mutex,以上都不是重点,
重点是优先级反转。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP