select
我可以使用或等待多个网络连接之一epoll
。我可以使用 等待信号sigwaitinfo
,或者添加一个在收到信号时运行的处理程序。
我如何等待网络套接字有传入流量,或者等待特定信号(在我的情况下是 SIGWINCH)?
我想到的一个想法是让信号处理程序将“环回”流量发送到某个打开的文件描述符,这样epoll
就可以等待它了。但我宁愿不实际创建任何文件。也许有办法创建两个直接相互连接的新文件描述符?
select
我可以使用或等待多个网络连接之一epoll
。我可以使用 等待信号sigwaitinfo
,或者添加一个在收到信号时运行的处理程序。
我如何等待网络套接字有传入流量,或者等待特定信号(在我的情况下是 SIGWINCH)?
我想到的一个想法是让信号处理程序将“环回”流量发送到某个打开的文件描述符,这样epoll
就可以等待它了。但我宁愿不实际创建任何文件。也许有办法创建两个直接相互连接的新文件描述符?
在 Linux 上,我会使用 来执行此操作,这会创建一个文件描述符,当给定信号传递时,它会轮询为可读(并且可以从中读取以查找有关信号的信息)。该描述符可以与套接字一起
signalfd(2)
添加到 监视的描述符中。epoll
您应该
SIGWINCH
首先阻止它,sigprocmask(2)
以便它不会被正常的信号处理程序处理。您可以使用它
pipe(2)
来为该样式创建一对连接的描述符;这是较旧和/或可移植代码库中此类场景的常用技术。eventfd(2)
不过,对于 Linux,我通常更喜欢更轻量的异步通知。单个线程有多种选项可以响应信号和 I/O。
1. 将信号转换为 I/O
这是您想到的方法,另一个答案也很好地涵盖了它。您已经掌握了旧的(可移植的)自管道技巧和特定于 Linux 的
signalfd
。这就是我要做的,并且我建议投票并接受其他答案。
2. 将 I/O 转换为信号
为了完整性,值得一提的是,您可以使用
fcntl
来管理信号,使用 F_SETOWN 和 O_ASYNC 在描述符准备好读取或写入时获取 SIGIO。使用 SA_SIGINFO 以及 Linux 上的显式 F_SETSIG,您将能够判断哪个描述符已准备就绪以及原因。
绝对比 #1 更尴尬,并且可能不合适,例如,如果您的某些描述符是永久可写的。但它可能适用于,例如,等待绑定套接字上的传入连接。
3. 使用原子屏蔽分别处理信号和 I/O
POSIX
pselect
和 Linuxppoll
让您可以使用 I/O 多路复用,而不会“错过”信号触发,方法是仅在多路复用调用期间自动解除所需信号的阻塞。select
重要的是,poll
这里容易发生种族歧视,本网站上的其他 问题也涵盖了这一点。