这是一个一般性问题 - 但是我已经多次遇到这个问题,但我仍然没有找到最好的解决方案。
假设您有一个多线程程序(例如 HTTP 应用程序服务器)并通过套接字(TCP、Unix 等)进行通信。主线程使用异步 IO 和 select() 或 poll() POSIX 调用来从/到套接字分派(dispatch)流量。还有工作线程处理请求并提供响应。为了将响应发送回客户端,工作线程“以某种方式”与主线程(轮询)同步。问题的核心是“如何”——就什么是有效的而言。我可以使用 pipe() - 基于套接字的 IPC 机制 - 但这在我看来是相当大的开销。我倾向于使用一些 pthread IPC 技术,如互斥锁、条件变量等……但这些不适用于 select() 或 poll()。
POSIX(和周围环境)中是否有解决此冲突的通用技术? 我想在 Windows 上有允许这样做的 WaitForMultipleObjects() 函数。
示例程序旨在说明一个问题,我知道我可以用不同的方式设计主/工作模式,但这不是我想要的。我在其他情况下也遇到过同样的情况。
最佳答案
您可以使用信号来触发工作线程,这将中断 select()
调用并返回 EINTR
。使用 pselect()
可以更轻松地做到这一点。
为了让它工作:
- 决定信号(或分配实时信号)
- 为其附加一个空的处理函数(如果信号被忽略,系统调用将自动重新启动)
- 至少在工作线程中阻止信号。
- 在
pselect()
中使用信号掩码参数在等待时解锁信号。
在线程之间,可以使用pthread_kill
将信号专门传递给工作线程。当另一个进程应该发送信号时,您可以确保信号在工作线程以外的所有线程中都被阻塞(因此它将被传递到那里),或者使用信号处理程序来查明信号是否被发送到工作线程,并使用 pthread_kill
显式转发它(工作线程仍然不需要在信号处理程序中执行任何操作)。
由于我的懒惰,我没有在线源代码查看器,但您可以克隆 LibreVISA git 树,并查看 src/messagepump.cpp
,其中此方法用于在另一个线程将文件描述符添加到监视列表后戳工作线程。
关于c - Posix select()/poll() 和 pthread IPC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24243222/