是否有最佳实践方法来从subprocess.Popen
以及zmq套接字轮询stdout / stderr?
就我而言,我的主程序产生了一个Popen子进程。子进程通过zmq发布消息,然后我想在主程序中订阅该消息。zmq.Poller
在多个zmq套接字上等待并不复杂,但是当我要将其与子进程本身的输出交错时,我不确定如何以最佳方式进行操作而不会冒着等待或不必要的循环的风险。
最后,我想这样使用它:
process = Popen([prog, '--publish-to', 'tcp://127.0.0.1:89890'],
stdout=subprocess.PIPE, stderr=subprocess.PIPE, ...)
for (origin, data) in interleave(process, 'tcp://127.0.0.1:89890'):
if origin == 'STDOUT': pass
if origin == 'STDERR': pass
if origin == 'ZMQ': pass
prog --publish-to tcp://127.0.0.1:89890
然后将打开zmq.PUB
套接字并发布数据,而interleave函数将订阅该套接字,并同时轮询stdout和stderr,yield
首先获取到达的任何数据。我知道如何用多个守护程序线程和队列定义
interleave
,但是我不知道这种方法是否可能对懒惰读取产生一些警告(即,stdout可能要等到程序结束时才能处理?)或其他。我还没有考虑过的事情(对于这样的任务,似乎也有很多开销)。我将感谢所有的想法或见解。
我的目标至少是Python 3.3 / 3.4,但如果事实证明,使用新的异步/等待工具要容易得多,我也可以将Python 3.5用于代码。
最佳答案
使用zmq.Poller
:http://pyzmq.readthedocs.io/en/latest/api/zmq.html#polling。您可以在那里注册zmq套接字和本机文件描述符(例如process.stdout.fileno()
和process.stderr.fileno()
),它将等待直到至少一个已注册源上的输入可用。
我不知道它是否适用于Windows,您应该尝试一下。
关于python - 来自Popen的stdout与来自ZMQ recv的消息交织,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38354051/