简体   繁体   English

我可以在同一个 asyncio 循环中写入和读取进程吗?

[英]Can I write to and read from a process in the same asyncio loop?

I have a process that reads input and writes output, like this doubler :我有一个读取输入和写入输出的进程,就像这个doubler
(in reality it's actually a black box and the input and the output are completely independent) (实际上它实际上是一个黑匣子,输入和输出完全独立)

#!/bin/bash
while read -r i; do
    sleep 0.$RANDOM
    echo $((i*2))
done

and a few functions in my Python code that feeds this process asynchronously:以及我的 Python 代码中的一些异步提供此过程的函数:

import asyncio
import subprocess
import random

class Feeder:
    def __init__(self):
        self.process = subprocess.Popen(['doubler.sh'],
                                        stdin=subprocess.PIPE)

    def feed(self, value):
        self.process.stdin.write(str(value).encode() + b'\n')
        self.process.stdin.flush()

feeder = Feeder()

async def feed_random():
    while True:
        feeder.feed(random.randint(0, 100))
        await asyncio.sleep(1)

async def feed_tens():
    while True:
        feeder.feed(10)
        await asyncio.sleep(3.14)

async def main():
    await asyncio.gather(
        feed_random(),
        feed_tens(),
    )

if __name__ == '__main__':
    asyncio.run(main())

This works well.这很好用。 But I would like to read the output of the process too, like this:但我也想阅读该过程的输出,如下所示:

...
stdout=subprocess.PIPE
...
for line in feeder.process.stdout:
    print("The answer is " + line.decode())

but that is blocking, so the feeding won't happen.但那是阻塞的,所以喂食不会发生。 Can this be done in the same asyncio loop?这可以在同一个异步循环中完成吗? Or do I need another thread?还是我需要另一个线程?

Something like this should work.像这样的事情应该有效。 In order to read from stdout asynchronously you have to switch to asyncio.subprocess .为了异步读取stdout您必须切换到asyncio.subprocess

import asyncio
import random

class Feeder:
    def __init__(self):
        self.process = None

    async def start_process(self):
        self.process = await asyncio.create_subprocess_exec('./doubler.sh',
            stdin=asyncio.subprocess.PIPE,
            stdout=asyncio.subprocess.PIPE)

    async def feed(self, value):
        self.process.stdin.write(str(value).encode() + b'\n')
        await self.process.stdin.drain()

feeder = Feeder()

async def feed_random():
    while True:
        asyncio.ensure_future(feeder.feed(random.randint(0, 100)))
        await asyncio.sleep(1)

async def feed_tens():
    while True:
        asyncio.ensure_future(feeder.feed(10))
        await asyncio.sleep(3.14)

async def read_feed():
    while True:
        line = await feeder.process.stdout.readline()
        print("The answer is " + line.decode('utf-8'))


async def main():
    await feeder.start_process()
    await asyncio.gather(
        feed_random(),
        feed_tens(),
        read_feed()
    )

if __name__ == '__main__':
    asyncio.run(main())

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 我可以使用 asyncio 读取和写入 multiprocessing.Pipe 吗? - Can I use asyncio to read from and write to a multiprocessing.Pipe? 两个进程实时读写同一个文件 - Two process read & write from/to the same file in real time 如何使用asyncio连续读取进程并在超时后将其杀死 - How to use asyncio to continously read from a process and kill it after a timeout 如何执行*异步*对异步传输对象的读/写操作 - How to perform *synchronous* read/write into/from a asyncio transport object 我可以使用单个文件作为缓冲区吗? 即同时写入和读取 - Can I use a single file as a buffer? I.e. write to and read from at same time 读取文件后如何再次写入文件(或使读写过程循环)? - How do i write again to a file after reading it (or make a loop for the read and write process )? 是否有原因我无法写入,然后使用 pandas 从同一个 csv 文件中读取? - Is there a reason I can't write to, and later read from the same csv file using pandas? 开始异步过程-我可以/应该使用asyncio吗? - Start an async process - can/should I use asyncio? 我如何从另一个线程和另一个循环等待 asyncio.Future - How Can I wait asyncio.Future from another thread and another loop 我该如何编写异步可选的常规程序? - How can I write asyncio coroutines that optionally act as regular functions?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM