使用pselect捕获套接字和信号事件

时间:2013-08-06 08:15:54

标签: c++ c linux sockets

我正在制作一个需要同时使用套接字io和共享内存的消息服务。无论输入来自何处,例程都是相同的,唯一的区别是本地消息将通过套接字通过共享内存和非本地消息传递。这两个事件都必须取消阻止相同的pselect调用。 在这一点上,我认为最好的选择可能是在将消息写入共享内存时发送信号并使用它来中断pselect调用,但我不确定如何做到这一点,或者即使它是最佳路由。

我不习惯使用信号。什么是实现这一目标的最佳方式?

5 个答案:

答案 0 :(得分:5)

我会考虑使用管道(请参阅pipe(2))或AF_UNIX本地unix(7) socket(2)(由caf评论)至少传输控件信息 - 用于同步 - 关于共享存储器(即告知它何时发生了变化,即通过共享存储器发送消息的时间等)。然后你仍然可以与例如多路复用poll(2)(或ppoll(2)pselect(2)等...)

我不认为使用信号的同步是正确的方法:信号难以正确(因此编码很棘手)并且它们不比在某些管道上交换几个字节更有效。

您考虑过使用MPI吗?

答案 1 :(得分:2)

如果您只想在进程之间发信号而不是传递数据,那么eventfd(参见eventfd(2))将允许您使用select(),其开销小于管道。与管道解决方案一样,这些流程需要父/子关系。

答案 2 :(得分:1)

如果您想使用信号,请使用sigqueue发送信号 - 您可以使用此信息发送整数有效负载,例如偏移到共享内存中。

确保使用sigaction注册您的信号处理程序并使用sa_sigaction回调:siginfo_t->si_int成员将包含该有效负载。

一般来说,我不确定我是否可以推荐使用这种机制而不是unix管道或eventfd,因为我不确定信号传递是否真的按照你希望的速度调整:基准确定。


PS。除了性能之外,有一个原因是信号感觉有点棘手,就是你失去了像inet或unix端口那样“众所周知”的会合点的机会,而是必须去寻找PID。此外,您必须非常小心屏蔽,以确保信号在您想要的地方传送。

PPS。你举起或发出一个信号 - 你不要扔它。这是例外情况。

答案 3 :(得分:0)

我做了一些额外的观察并遇到了signalfd(2)。我相信这将是最好的解决方案 - 非常类似于Basile Starynkevitch的建议,但没有标准管道的开销,而是在内核而不是用户空间内完成。

答案 4 :(得分:-2)

管道+选择+队列+锁定,没有别的。