使用System V和POSIX信号量之间的权衡是什么?
w1e3prcc1#
来自O'Reilly:
o8x7eapl2#
在单独的进程(而不是线程)中使用POSIX共享/命名信号量有两个主要问题:POSIX信号量没有提供在持有信号量锁的不同进程死时唤醒等待进程的机制。这种缺乏清理可能会导致僵尸信号量,这将导致任何其他或后续进程试图使用它们来死锁。也没有POSIX方法列出操作系统中的信号量,以尝试识别和清理它们。SysV IPC上的POSIX部分确实指定了列出和操作全局SysV IPC资源的IPC和ipcrm工具。没有为POSIX IPC指定这样的工具或机制,尽管在Linux上,这些资源通常可以在/shm下找到。这意味着在错误的时间向错误的进程发送终止信号可能会导致交互进程的整个系统死锁,直到重新启动。
另一个缺点是对POSIX信号量使用文件语义。这意味着可以有多个名称相同但状态不同的共享信号量。例如,一个进程调用sem_open,然后调用sem_unlink,然后调用sem_lose。此进程仍然可以使用信号量,就像在关闭文件之前取消链接打开的文件一样。进程2在进程1的sem_unlink和sem_lose调用之间对同一信号量调用sem_open,并(根据文档)获得一个全新的信号量,该信号量具有与进程1相同的名称,但处于不同的状态。两个具有相同名称的共享信号量独立运行会破坏共享信号量的目的。
以上限制之一使POSIX共享信号量在实际系统中无法使用,无法保证永远不会发送不可捕获的信号。限制二可以通过仔细编码来缓解,假定可以控制将使用给定信号量的所有代码。坦率地说,他们能以现在的样子进入标准,这太令人惊讶了。
zc0qhyus3#
我知道这很古老,但为了那些仍在阅读这篇Google文章的读者的利益,我发现使用System V信号量而不是POSIX(系统级)信号量的首要原因是能够以一种无论进程如何退出都会由内核自动返回的方式获取信号量资源。
我同意很少使用多个(原子)信号量操作(尽管它们在试运行期间很有用),而且System V接口很奇怪,但根本没有办法使用POSIX信号量可靠地实现相同的清理语义。
kmb7vmvb4#
在性能方面,在Linux下,POSIX信号量基于futex。这使得它们比SYSV信号量更高效。SYSV信号量要求系统调用P()/V()操作。因此,这系统地触发用户到内核空间上下文的切换,反之亦然。在POSIX版本中,如果信号量上没有争用,底层Futex会让调用者留在用户空间(P()/V()操作是在用户空间中使用可用的原子操作完成的)。只有在出现争用的情况下才会切换到内核模式。因此,在使用POSIX信号量的应用程序中,用户到内核空间上下文切换的数量较少。这会让他们更快。
4条答案
按热度按时间w1e3prcc1#
来自O'Reilly:
o8x7eapl2#
在单独的进程(而不是线程)中使用POSIX共享/命名信号量有两个主要问题:POSIX信号量没有提供在持有信号量锁的不同进程死时唤醒等待进程的机制。这种缺乏清理可能会导致僵尸信号量,这将导致任何其他或后续进程试图使用它们来死锁。也没有POSIX方法列出操作系统中的信号量,以尝试识别和清理它们。SysV IPC上的POSIX部分确实指定了列出和操作全局SysV IPC资源的IPC和ipcrm工具。没有为POSIX IPC指定这样的工具或机制,尽管在Linux上,这些资源通常可以在/shm下找到。这意味着在错误的时间向错误的进程发送终止信号可能会导致交互进程的整个系统死锁,直到重新启动。
另一个缺点是对POSIX信号量使用文件语义。这意味着可以有多个名称相同但状态不同的共享信号量。例如,一个进程调用sem_open,然后调用sem_unlink,然后调用sem_lose。此进程仍然可以使用信号量,就像在关闭文件之前取消链接打开的文件一样。进程2在进程1的sem_unlink和sem_lose调用之间对同一信号量调用sem_open,并(根据文档)获得一个全新的信号量,该信号量具有与进程1相同的名称,但处于不同的状态。两个具有相同名称的共享信号量独立运行会破坏共享信号量的目的。
以上限制之一使POSIX共享信号量在实际系统中无法使用,无法保证永远不会发送不可捕获的信号。限制二可以通过仔细编码来缓解,假定可以控制将使用给定信号量的所有代码。坦率地说,他们能以现在的样子进入标准,这太令人惊讶了。
zc0qhyus3#
我知道这很古老,但为了那些仍在阅读这篇Google文章的读者的利益,我发现使用System V信号量而不是POSIX(系统级)信号量的首要原因是能够以一种无论进程如何退出都会由内核自动返回的方式获取信号量资源。
我同意很少使用多个(原子)信号量操作(尽管它们在试运行期间很有用),而且System V接口很奇怪,但根本没有办法使用POSIX信号量可靠地实现相同的清理语义。
kmb7vmvb4#
在性能方面,在Linux下,POSIX信号量基于futex。这使得它们比SYSV信号量更高效。
SYSV信号量要求系统调用P()/V()操作。因此,这系统地触发用户到内核空间上下文的切换,反之亦然。
在POSIX版本中,如果信号量上没有争用,底层Futex会让调用者留在用户空间(P()/V()操作是在用户空间中使用可用的原子操作完成的)。只有在出现争用的情况下才会切换到内核模式。因此,在使用POSIX信号量的应用程序中,用户到内核空间上下文切换的数量较少。这会让他们更快。