使用System V和Posix信号量之间的权衡取舍是什么?
来自O'Reilly:
System V和POSIX信号量实现之间的一个显着区别是,在System V中,您可以控制信号量计数可以增加或减少的程度; 而在POSIX中,信号量计数增加并减少1.
POSIX信号量不允许操纵信号量权限,而System V信号量允许您将信号量的权限更改为原始权限的子集.
信号量的初始化和创建在POSIX信号量中是原子的(从用户的角度来看).
从使用角度来看,System V信号量是笨拙的,而POSIX信号量是直截了当的
POSIX信号量的可扩展性(使用未命名的信号量)远高于System V信号量.在用户/客户端场景中,每个用户创建自己的服务器实例,最好使用POSIX信号量.
System V信号量,在创建信号量对象时,创建一个信号量数组,而POSIX信号量只创建一个信号量.由于此功能,与POSIX信号量相比,System V信号量中信号量创建(内存占用方面)的成本更高.
据说POSIX信号量性能优于基于System V的信号量.
POSIX信号量为进程范围的信号量而不是系统范围的信号量提供了一种机制.因此,如果开发人员忘记关闭信号量,则在进程退出时清除信号量.简单来说,POSIX信号量为非持久信号量提供了一种机制.
在单独的进程(而不是线程)中使用POSIX共享/命名信号量的两个主要问题:POSIX信号量不提供在不同进程在保持信号量锁定时死亡时唤醒等待进程的机制.这种缺乏清理会导致僵尸信号灯,这将导致试图使用它们死锁任何其他或后续过程.也没有POSIX方法列出操作系统中的信号量以尝试识别和清理它们.SysV IPC上的POSIX部分确实指定了ipcs和ipcrm工具来列出和操作全局SysV IPC资源.没有为POSIX IPC指定此类工具甚至机制,但在Linux上,这些资源通常可以在/ shm下找到.这意味着在错误的时间向错误的进程发出KILL信号可能会导致整个交互过程系统死锁,直到重新启动.
另一个缺点是对POSIX信号量使用文件语义.这意味着可以有多个具有相同名称但在不同状态的共享信号量.例如,一个进程调用sem_open,然后在sem_close之前调用sem_unlink.此过程仍然可以使用信号量,就像在关闭它之前取消链接打开文件一样.进程2在进程1的sem_unlink和sem_close调用之间的同一个信号量上调用sem_open,并且(根据文档)获得一个具有相同名称的全新信号量,但处于与进程1不同的状态.两个具有相同名称的共享信号量独立运作会破坏共享信号量的目的.
上述限制一个让POSIX共享的信号在真实世界的系统无法使用没有保证,无法捕获的信号不能被发送.通过仔细编码可以减轻限制二,假设控制将使用给定信号量的所有代码.坦率地说,它有点令人惊讶,因为它们已经成为标准.
我知道这已经过时了,但是为了那些仍在阅读Google礼貌的人们的利益,我发现在POSIX(系统级)信号量上使用System V信号量的第一个原因是能够以某种方式获取信号量资源内核自动返回NO MATTER过程如何退出.
我同意很少使用多个(原子)信号量操作(尽管它们在分段期间很有用),并且System V接口很奇怪,但是根本无法用POSIX信号量可靠地实现相同的清理语义.