我正在实施一个运行游戏服务器的系统。我有一个进程(“游戏控制器”),它创建两个管道对并分叉一个孩子。子进程将其STDIN复制到一个管道,并将其STDOUT和STDERR复制到另一个管道,然后运行execlp()
以运行游戏代码。
游戏控制器将有两个线程。第一个将阻塞accept()
在命名的UNIX套接字上接收来自另一个应用程序的输入,第二个线程阻止read()
来自游戏服务器的输出和错误管道。
有时,第一个线程会收到一个命令,将字符串发送到游戏服务器的stdin管道。此时,不知何故,我需要从read()
停止第二个线程,以便第一个线程可以从out和error管道读取回复。
(值得注意的是,我会知道回复的字符/行数是多少,所以我知道何时停止阅读并让第二个线程重新开始读取,重置过程。)
如何暂时将读取控件切换到另一个线程,如上所述?
答案 0 :(得分:4)
有几种选择。一种方法是让第二个线程处理所有的读取,并给第一个线程一个信号,告诉它将输入传回。但这有点复杂;你需要设置一个在线程之间发送信号的方法,并确保第一个线程在第二个线程读取它之前告诉第二个线程它想要输入并自己处理它。各种竞争条件都有可能使你的代码无法预测。
另一种选择是避免使用线程。只需使用select(2)
(或poll(2)
)允许一个线程一次等待几个文件描述符上的活动。 select
允许您指出您感兴趣的文件描述符集。只要其中一个活动发生(连接可以接受,数据可供读取),select
将返回,指示已准备好的文件描述符集。然后,您可以接受或读取相应的描述符,完成后,再次循环并再次调用select
以等待下一个I / O事件。