讨论——操作系统里面的信号量与互斥锁

[复制链接]
815|16
手机看帖
扫描二维码
随时随地手机跟帖
baimiaocun2015|  楼主 | 2017-3-18 16:51 | 显示全部楼层 |阅读模式
如题,,这个还是常见的,特别是针对操作系统开发 的朋友的,,,不多说的,直接来讨论的哈

关于两者的,,先才能够定义上解释下的——
信号量:用在多线程多任务同步的,一个线程完成了某一个动作就通过信号量告诉别的线程,别的线程再进行某些动作(大家都在semtake的时候,就阻塞在 哪里)。

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

baimiaocun2015|  楼主 | 2017-3-18 16:52 | 显示全部楼层
关于两者的区别的;
互斥量用于线程的互斥,信号线用于线程的同步。这是互斥量和信号量的根本区别,也就是互斥和同步之间的区别。  
互斥:是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的。  
        同步:是指在互斥的基础上(大多数情况),通过其它机制实现访问者对资源的有序访问。在大多数情况下,同步已经实现了互斥,特别是所有写入资源的情况必定是互斥的。少数情况是指可以允许多个访问者同时访问资源  

使用特权

评论回复
baimiaocun2015|  楼主 | 2017-3-18 16:54 | 显示全部楼层
这一点比较重要的:
互斥量值只能为0/1,信号量值可以为非负整数。  
也就是说,一个互斥量只能用于一个资源的互斥访问,它不能实现多个资源的多线程互斥问题。信号量可以实现多个同类资源的多线程互斥和同步。当信号量为单值信号量是,也可以完成一个资源的互斥访问。

使用特权

评论回复
baimiaocun2015|  楼主 | 2017-3-18 16:55 | 显示全部楼层
还有就是作用于跟上锁情况的存在区别的:
作用域不同
        信号量: 进程间或线程间(linux仅线程间)
        互斥锁: 线程间
上锁情况不同
        信号量: 只要信号量的value大于0,其他线程就可以sem_wait成功,成功后信号量的value减一。若value值不大于0,则sem_wait阻塞,直到sem_post释放后value值加一
        互斥锁: 只要被锁住,其他任何线程都不可以访问被保护的资源

使用特权

评论回复
baimiaocun2015|  楼主 | 2017-3-18 16:56 | 显示全部楼层
在就信号量的详细解释的坐下阐述的:

    信号量,是可以用来保护两个或多个关键代码段,这些关键代码段不能并发调用。在进入一个关键代码段之前,线程必须获取一个信号量。如果关键代码段中没有任何线程,那么线程会立即进入该框图中的那个部分。一旦该关键代码段完成了,那么该线程必须释放信号量。其它想进入该关键代码段的线程必须等待直到第一个线程释放信号量。

使用特权

评论回复
baimiaocun2015|  楼主 | 2017-3-18 16:56 | 显示全部楼层
信号量分类
        (1)二进制信号量(binary semaphore):只允许信号量取0或1值,其同时只能被一个线程获取。
        (2)整型信号量(integer semaphore):信号量取值是整数,它可以被多个线程同时获得,直到信号量的值变为0。
        (3)记录型信号量(record semaphore):每个信号量s除一个整数值value(计数)外,还有一个等待队列List,其中是阻塞在该信号量的各个线程的标识。当信号量被释放一个,值被加一后,系统自动从等待队列中唤醒一个等待中的线程,让其获得信号量,同时信号量再减一。

使用特权

评论回复
baimiaocun2015|  楼主 | 2017-3-18 16:57 | 显示全部楼层
这一点很重重要:
       信号量通过一个计数器控制对共享资源的访问,信号量的值是一个非负整数,所有通过它的线程都会将该整数减一。如果计数器大于0,则访问被允许,计数器减1;如果为0,则访问被禁止,所有试图通过它的线程都将处于等待状态。  
        计数器计算的结果是允许访问共享资源的通行证。因此,为了访问共享资源,线程必须从信号量得到通行证, 如果该信号量的计数大于0,则此线程获得一个通行证,这将导致信号量的计数递减,否则,此线程将阻塞直到获得一个通行证为止。当此线程不再需要访问共享资源时,它释放该通行证,这导致信号量的计数递增,如果另一个线程等待通行证,则那个线程将在那时获得通行证。

使用特权

评论回复
baimiaocun2015|  楼主 | 2017-3-18 16:58 | 显示全部楼层
好了,,就基本概念的西安说这些的,,大家有更好的分享的也贡献出来的哈

使用特权

评论回复
baimiaocun2015|  楼主 | 2017-3-18 17:00 | 显示全部楼层
还有一点的哈:
信号量的关键操作
        操作代码分别为Win32以及POSIX
        (1)创建
            CreateSemaphore、sem_init
            创建信号灯,可以将信号量中的值初始化为某个需要的非负整数。
        (2)等待(也即PV中的P)
            WaitForSingleObject、sem _wait
            线程等待信号量,如果值大于0,则获得,值减1;如果值等于0,则直线程进入等待状态,直到信号量值大于0或者超时。
        (3)释放(也即PV中的V)
            ReleaseMutex、sem _post
            执行释放信号量,则值加一;如果此时有正在等待的线程,则唤醒该线程。
        (4)销毁   
            CloseHandle、sem_destroy
            被注销的信号灯sem要求已没有线程在等待该信号灯,否则返回-1

使用特权

评论回复
angerbird| | 2017-3-19 21:36 | 显示全部楼层
互斥量用于线程的互斥,信号量用于线程的同步。这是互斥量和信号量的根本区别,也就是互斥和同步之间的区别。
这个还是不好理解的。。

使用特权

评论回复
comeon201208| | 2017-3-19 22:19 | 显示全部楼层
关于信号量的还是非常复杂的,,我刚看完一遍的也没怎理解的。

使用特权

评论回复
shenmu2012| | 2017-3-26 18:14 | 显示全部楼层
baimiaocun2015 发表于 2017-3-18 17:00
还有一点的哈:
信号量的关键操作
        操作代码分别为Win32以及POSIX

这个操作的过程很重要的

使用特权

评论回复
shenmu2012| | 2017-3-26 18:15 | 显示全部楼层
信号量的操作的,,我记得是现在初始化部分创建一个信号量的,,然后再需要改信号量之前post一个信号量的

使用特权

评论回复
shenmu2012| | 2017-3-26 18:15 | 显示全部楼层
然后就是在程序运行到需要改信号量的地方在来消耗掉该信号量的,也就是pend一个信号量的。。

使用特权

评论回复
shenmu2012| | 2017-3-26 18:17 | 显示全部楼层
该需要信号量的地方执行完成后最好在再post一个信号量的放那,一方有其他任务需要用的

使用特权

评论回复
shenmu2012| | 2017-3-26 18:17 | 显示全部楼层
最后就是销毁一个信号量的,,该部分是放在所有的任务执行完成之后的。

使用特权

评论回复
comeon201208| | 2017-3-27 22:57 | 显示全部楼层
楼上介绍的非常好,,那么问下对于互斥信号量的有怎样处理呢?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

27

主题

1870

帖子

2

粉丝