需要解决方法:Python的select.select()与subprocess的stdout不兼容?
在我的主Python程序中,我用以下代码启动了一个子程序:
child = subprocess.Popen(..., stdout=subprocess.PIPE, stdin=subprocess.PIPE)
顺便提一下,子程序是一个PHP脚本,需要和Python程序进行双向通信。
主Python程序实际上需要监听来自多个渠道的通信——其他使用相同代码启动的PHP脚本,或者来自socket.accept()
的socket对象。我想使用select.select()
,因为这是等待来自不同来源输入的最有效方法。
我遇到的问题是,在Windows下,select.select()
无法与子进程的stdout文件描述符一起使用(这个问题有文档说明),看起来我不得不:
- A) 不停地检查PHP脚本,看它们是否有输出到stdout。(这个系统需要非常灵敏,我需要每秒检查至少1,000次!)
- B) 让PHP脚本连接到主进程,通过socket进行通信,而不是使用stdout/stdin。
我可能会选择方案(B),因为我不想让系统以如此高的频率进行轮询,但感觉用socket重新连接真是浪费资源,毕竟stdout/stdin本来就可以满足需求。
有没有其他解决方案可以让我同时使用stdout 和 select.select()
?
1 个回答
4
很遗憾,在Windows上使用管道的效果没有在Unix上那么好,这就是其中一个例子。在Windows上,更好的解决办法可能是让你的主程序创建线程,去监听每一个子进程。如果你知道从子进程中期望得到的数据的粒度,你可以在每个线程中进行阻塞读取,这样当输入输出不再阻塞时,线程就会被唤醒。
另外,虽然我不确定这是否适合你的项目,但你可以考虑使用类似Unix的系统,或者在Windows上使用类似Unix的层(比如Cygwin),在那样的环境下,select.select()
可以在子进程的管道上正常工作。