交换来自Popen的stdout和来自ZMQ recv的消息

时间:2016-07-13 14:09:10

标签: python zeromq popen

是否有最佳实践方法从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,但如果使用新的async / await工具变得更容易,我也可以使用Python 3.5代码。

1 个答案:

答案 0 :(得分:1)

使用zmq.Pollerhttp://pyzmq.readthedocs.io/en/latest/api/zmq.html#polling。您可以在那里注册zmq套接字和本机文件描述符(例如process.stdout.fileno()process.stderr.fileno()),它将等到至少一个已注册的源上有输入。

我不知道它是否适用于Windows,你应该试试。