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