那么,它们在哪里和如何使用呢?
首先,注意Ben的答案是正确的。据我所知,POSIX中实时信号的整个目的是作为AIO、消息队列通知、定时器到期和应用程序定义信号(内部和进程间)的实时传递机制。
话虽如此,信号总体来说是一种非常糟糕的方法:
sigwait
(或Linux的signalfd
扩展)而不是信号处理程序来处理信号,则它们与其他IPC/通知机制一样差,仍然存在潜在的劣势。异步IO更好地通过忽略设计不良的POSIX AIO API实现,并创建一个线程来执行正常的阻塞IO并在操作完成时调用pthread_cond_signal
或sem_post
。或者,如果您能承担一点性能成本,甚至可以通过管道或socketpair将刚刚读取的数据转发回自己,并使用select
或poll
在主线程中异步读取常规文件,就像处理套接字/管道/ ttys一样。
这是一个老问题,但仍然存在。
Linux中的glibc(NPTL)使用两个实时信号来实现POSIX线程。它们对用户隐藏(通过调整最小/最大数量常量)。所有需要将库调用传播到所有线程的事件(例如setuid
)都通过这些信号完成:调用线程发送信号以将更改应用于所有线程,等待确认并继续执行。
使用实时信号的其他原因是有一些应用程序需要与各种外部设备进行交互,而这些交互方式是通过多种手段实现的(串口IO,甚至是直接寻址某些比你认识的大多数人都要老的卡)。这就是所谓的“实时”应用程序——它与真实世界以真实世界的时间进行交互,而不是以“计算机时间”进行交互。
它的许多功能都在一个守护进程中,该进程处于主循环中:处理事件、读取信息、将结果写入串口、将事物存储在数据库中等等,然后循环处理下一个事件。机器上的其他进程(用户进程)从数据库中读取信息、显示信息等等。这些其他进程中的用户可以向守护进程发送各种信号,以通知它各种条件:停止、更改输入数据等等。例如,用户进程发送一个“停止”信号,守护进程的信号处理程序只需两行代码,设置一个标志变量。当守护进程有机会并且方便时,它就会停止。这个“中断”代码非常简单、快速和非侵入性。但它达到了目的,不需要复杂的IPC结构,并且运行得非常好。
是的,在实时应用程序中,这些信号有其存在的原因。如果得到适当处理,它们可以正常工作,谢谢。
select
命令是无用的。它总是表示这些文件可以进行读写操作。这不是设计缺陷;即使select
命令只在可以立即从缓存中读取数据(或在可用空闲缓存内存时可以写入)时显示它们是可读的(或可写的),也会存在竞争条件 - 在select
返回后,缓存可用性状态可能会发生变化,并且在内核空间中read
/write
命令可能会进入睡眠状态。当然,另一种替代方案是对要访问的文件部分进行mmap
和mlock
(如果要写入,则还需fallocate
),然后使用普通 IO。 - R.. GitHub STOP HELPING ICEmmap
和mlock
是阻塞的,我不认为有这些系统调用的任何异步版本。 - Ben Voigt