0

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

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

4

5 回答 5

5

我会考虑使用管道(参见pipe(2))或AF_UNIX本地unix(7) socket(2)(由caf评论)至少传输控制信息 - 用于同步 - 关于共享内存(即告诉它何时有已更改,即当消息已通过共享内存等发送时)。然后你仍然可以多路复用,例如poll(2) (or ppoll(2)or pselect(2)etc...)

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

你考虑过使用MPI吗?

于 2013-08-06T08:22:27.473 回答
2

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

于 2013-08-06T08:26:08.933 回答
1

如果您想使用信号,请使用sigqueue发送它们 - 您可以使用它发送整数有效负载,例如共享内存的偏移量。

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

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


PS。撇开性能不谈,信号感觉有点恶心的一个原因是您失去了拥有像 inet 或 unix 端口这样的“知名”集合点的机会,而不得不去寻找 PID。此外,您必须非常小心掩蔽以确保将信号传递到您想要的位置。

聚苯乙烯。你提出或发送一个信号 - 你不扔它。那是例外。

于 2013-08-06T09:49:42.283 回答
0

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

于 2013-08-06T19:39:51.980 回答
-2

管道+选择+队列+锁,仅此而已。

于 2013-08-06T08:36:06.437 回答