将来自 Popen 的标准输出与来自 ZMQ recv 的消息交织在一起
Interleaving stdout from Popen with messages from ZMQ recv
是否有从 subprocess.Popen
以及 zmq 套接字轮询 stdout/stderr 的最佳实践方法?
在我的例子中,我的主程序生成了一个 Popen 子进程。子进程通过 zmq 发布消息,然后我想在我的主程序中订阅它。
在多个 zmq 套接字上等待并不复杂 zmq.Poller
但是当我想将它与我的子进程本身的输出交错时,我不确定如何以最好的方式做到这一点而不冒等待或有不必要的循环。
最后,我想这样使用它:
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
套接字并发布数据,而交错函数将订阅它并轮询 stdout 和 stderr,yield
ing 到达它的任何数据首先.
我知道如何使用多个守护进程线程和队列定义 interleave
,但我不知道这种方法是否有一些关于惰性读取的注意事项(即 stdout 可能要到最后才会处理程序的?)或其他我还没有考虑过的事情(对于这样的任务来说似乎也是相当多的开销)。
我将感谢所有想法或见解。
我的目标是至少 Python 3.3/3.4,但如果使用新的 async/await 工具会更容易,我也可以使用 Python 3.5 作为代码.
使用zmq.Poller
:http://pyzmq.readthedocs.io/en/latest/api/zmq.html#polling。您可以在那里注册 zmq 套接字和本机文件描述符(例如 process.stdout.fileno()
和 process.stderr.fileno()
),它会一直等待,直到输入在至少一个已注册的源上可用。
我不知道它在Windows中是否有效,你应该试试。
是否有从 subprocess.Popen
以及 zmq 套接字轮询 stdout/stderr 的最佳实践方法?
在我的例子中,我的主程序生成了一个 Popen 子进程。子进程通过 zmq 发布消息,然后我想在我的主程序中订阅它。
在多个 zmq 套接字上等待并不复杂 zmq.Poller
但是当我想将它与我的子进程本身的输出交错时,我不确定如何以最好的方式做到这一点而不冒等待或有不必要的循环。
最后,我想这样使用它:
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
套接字并发布数据,而交错函数将订阅它并轮询 stdout 和 stderr,yield
ing 到达它的任何数据首先.
我知道如何使用多个守护进程线程和队列定义 interleave
,但我不知道这种方法是否有一些关于惰性读取的注意事项(即 stdout 可能要到最后才会处理程序的?)或其他我还没有考虑过的事情(对于这样的任务来说似乎也是相当多的开销)。
我将感谢所有想法或见解。
我的目标是至少 Python 3.3/3.4,但如果使用新的 async/await 工具会更容易,我也可以使用 Python 3.5 作为代码.
使用zmq.Poller
:http://pyzmq.readthedocs.io/en/latest/api/zmq.html#polling。您可以在那里注册 zmq 套接字和本机文件描述符(例如 process.stdout.fileno()
和 process.stderr.fileno()
),它会一直等待,直到输入在至少一个已注册的源上可用。
我不知道它在Windows中是否有效,你应该试试。