【问题标题】:Asyncio stream process data with pipe between two subprocesses在两个子进程之间使用管道的异步流处理数据
【发布时间】:2021-02-16 09:42:07
【问题描述】:

您好,我在这里找不到示例的解决方案。我找到了https://stackoverflow.com/a/36666420/6089311,但是没有流读。

我想运行两个独立于 python 程序的子进程(在后台运行)。第一个子进程通过管道为第二个进程提供数据,我想通过流的方式对 stdout 行进行一些处理。

下面的例子被屏蔽了,但我不知道为什么:

import asyncio
import os

async def foo():
    read, write = os.pipe()
    process_1 = await asyncio.create_subprocess_exec('ls', stdout=write)
    process_2 = await asyncio.create_subprocess_exec('wc', stdin=read, stdout=asyncio.subprocess.PIPE)
    
    async for l in process_2.stdout:
        # streaming process data
        print(l)
    
    os.close(write)
    os.close(read)

await foo() # jupyter call
# async.run(foo()) # python call

【问题讨论】:

  • 也许你应该在链接中使用close
  • 您是否收到错误消息?始终将有问题的完整错误消息(从“Traceback”一词开始)(不是评论)作为文本(不是屏幕截图,不是链接到外部门户)。还有其他有用的信息。

标签: python python-3.x subprocess python-asyncio


【解决方案1】:

如果我将 close() 移动到您的链接等位置,代码对我有用。

但这可能不是你所期望的。

import asyncio
import os

async def foo():
    read, write = os.pipe()
    
    process_1 = await asyncio.create_subprocess_exec('ls', stdout=write)
    os.close(write)

    process_2 = await asyncio.create_subprocess_exec('wc', stdin=read, stdout=asyncio.subprocess.PIPE)
    os.close(read)
    
    async for line in process_2.stdout:
        # streaming process data
        print(line.decode())

#await foo() # jupyter call
asyncio.run(foo()) # python call

最终我可以稍后关闭read,但我必须在for-loop 之前关闭write

import asyncio
import os

async def foo():
    read, write = os.pipe()
    
    process_1 = await asyncio.create_subprocess_exec('ls', stdout=write)
    process_2 = await asyncio.create_subprocess_exec('wc', stdin=read, stdout=asyncio.subprocess.PIPE)
    
    os.close(write)

    async for line in process_2.stdout:
        # streaming process data
        print(line.decode())

    os.close(read)

#await foo() # jupyter call
asyncio.run(foo()) # python call

【讨论】:

  • 是不是说process_1先把所有的数据都写到pipe里,然后把所有的数据都存到RAM里?如果 process_1 是大文件的cat 并且 process_2 处理来自标准输入的数据会很慢?
  • 我想在 process_1 运行时从 process_2 读取数据。
  • 对不起,这是我对管道工作原理的误解......我不明白为什么我应该在阅读流程之前关闭管道并忘记子流程有另一个副本管道。是的,你是对的,它有效,谢谢!
  • 如果我在阅读 process_2.stdout 之前不关闭写入管道,可以解释为什么程序被阻止(对于其他用户来说应该没问题)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-10-16
  • 2014-06-20
  • 2020-01-06
  • 1970-01-01
  • 1970-01-01
  • 2011-06-18
相关资源
最近更新 更多