signalfd 和 sigwaitinfo 之间的区别?

signalfd 和 sigwaitinfo 之间的区别?

我浏览了示例和手册页,但无法弄清楚 signalfd 和 sigwaitinfo 之间的区别除了语法之外,两者都在做相同的事情,即等待信号将其详细信息存储到某个结构中。

在手册页中是这样写的。这提供了使用信号的替代方案 handler 或 sigwaitinfo(2),其优点是可以通过 select(2)、poll(2) 和 epoll(7) 监视文件描述符。

谁能帮我解释一下这到底是什么意思吗?

答案1

select(2)、poll(2) 和 epoll(7) 系统调用只是等待文件描述符(表示 I/O 通道的小整数)上的事件的一种方法。事件可以包括“读取数据”、“准备写入”等。你的代码组成了一组最终会产生事件的文件描述符,然后调用 select()、poll() 或 epoll() 使程序等待,直到数据到达,内核将套接字连接到其他主机,描述符有错误,无论如何。

signalfd(2) 添加一个新事件:信号已到达。在 unix/linux/*BSD 中,“信号”或多或少是一个异步事件:CPU 试图执行非法指令、I/O 已准备好、代码除以零、调制解调器挂起。 signalfd(2) 允许您创建一个文件描述符,可在 select()、poll()、epoll() 中使用,当信号到达时它会产生一个事件。

在过去,您会指定一个处理函数,当信号到达时内核会神奇地调用该函数(也称为“上行调用”)。如果您使用 sigaction() 系统调用来告诉内核您希望它调用什么函数,您将获得与 sigwaitinfo() 相同的信息。

使用 signal() 或 sigaction() 设置处理程序函数而不是 signalfd() 之间的区别在于,处理程序函数可以随时神奇地调用:部分代码必须是可重入的(不仅仅是线程安全的,请注意)你)来处理信号的“随时”性质。使用 signalfd(),信号只是代码事件循环中要处理的另一个事件。您的代码会像往常一样执行。

sigwaitinfo() 会使您的代码暂停,直到您指定的信号到达为止。在该信号到达之前,您的代码不会执行任何操作。没有事件循环,什么也没有。看起来 sigwaitinfo() 也是 Linux 内核中实时功能的一部分。 sigwaitinfo() 可以被认为是在代码中指定一个位置,以便内核在信号到达时调用,而不是指定要调用的函数。

添加:

我刚刚发现一篇关于“自管技巧”的博客文章”。显然,处理信号和基于选择的 I/O 不仅在代码方面不方便,而且还可能遭受“令人讨厌的竞争条件”。自管道技巧通过基本上执行 signalfd(2) 所做的事情来解决这个问题,但是全部都在用户空间中,并且以更多代码为代价。

答案2

简而言之:当您使用 sigwaitinfo() 时,您只能等待信号。当您将 signalfd() 与 poll/select/etc 结合使用时,您可以等待可以通过文件描述符访问的任何事件(文件 IO、timerfd、eventfd 等)。

相关内容