我遇到了一个非常简单的问题—我无法与进程的stdout通信. 这个过程是一个简单的秒表,所以我可以启动它,停止并得到当前时间.

秒表的代码是:

import argparse
import time

def main() -> None:
    parser = argparse.ArgumentParser()
    parser.add_argument('start', type=int, default=0)

    start = parser.parse_args().start
    
    while True:
        print(start)
        start += 1
        time.sleep(1)

if __name__ == "__main__":
    main()

它的管理者是:

import asyncio


class RobotManager:
    def __init__(self):
        self.cmd = ["python", "stopwatch.py", "10"]
        self.robot = None

    async def start(self):
        self.robot = await asyncio.create_subprocess_exec(
            *self.cmd,
            stdout=asyncio.subprocess.PIPE,
        )

    async def stop(self):
        if self.robot:
            self.robot.kill()
            stdout = await self.robot.stdout.readline()
            print(stdout)
            await self.robot.wait()
        self.robot = None


async def main():
    robot = RobotManager()
    await robot.start()
    await asyncio.sleep(3)
    await robot.stop()
    await robot.start()
    await asyncio.sleep(3)
    await robot.stop()

asyncio.run(main())

stdout.readline每次返回一个空字节串.

stdout = await self.robot.stdout.readline()更改为stdout, _ = await self.robot.communicate()时,结果仍然是一个空字节串.

当在RobotManager.start方法的末尾添加await self.robot.stdout.readline()时,它将永远挂起.

但是,当删除stdout=asyncio.subprocess.PIPE和所有readline调用时,子进程会按预期打印到终端.

如何正确读取子进程stdout?

推荐答案

在这种情况下,不能使用"proc. communication";它不适合这个目的,因为OP想要中断正在运行的进程.Python文档中的示例代码还展示了如何在这些情况下直接读取管道stdout,所以原则上这样做没有什么错.

主要的问题是秒表进程正在缓冲输出. try 使用命令:["python", "-u", "stopwatch.py", "3"] 为了调试,添加一些打印来指示机器人何时开始和结束也会有所帮助.以下是我的工作:

class RobotManager:
    def __init__(self):
        self.cmd = ["python", "-u", "stopwatch.py", "3"]
        self.robot = None

    async def start(self):
        print("======Starting======")
        self.robot = await asyncio.create_subprocess_exec(
            *self.cmd,
            stdout=asyncio.subprocess.PIPE,
        )
        
    async def stop(self):
        if self.robot:            
            self.robot.kill()
            stdout = await self.robot.stdout.readline()
            while stdout:
                print(stdout)
                stdout = await self.robot.stdout.readline()            
            await self.robot.wait()
            print("======Terminated======")
        self.robot = None

Python相关问答推荐

计算所有前面行(当前行)中列的值

通过优化空间在Python中的饼图中添加标签

将整组数组拆分为最小值与最大值之和的子数组

Matlab中是否有Python的f-字符串等效物

难以在Manim中正确定位对象

PywinAuto在Windows 11上引发了Memory错误,但在Windows 10上未引发

Python上的Instagram API:缺少client_id参数"

如何在Python中将returns.context. DeliverresContext与Deliverc函数一起使用?

非常奇怪:tzLocal.get_Localzone()基于python3别名的不同输出?

管道冻结和管道卸载

为什么以这种方式调用pd.ExcelWriter会创建无效的文件格式或扩展名?

ThreadPoolExecutor和单个线程的超时

Pandas GroupBy可以分成两个盒子吗?

如何使用SentenceTransformers创建矢量嵌入?

Flask运行时无法在Python中打印到控制台

30个非DATETIME天内的累计金额

如何从数据框列中提取特定部分并将该值填充到其他列中?

查找查找表中存在的列值组合

如果服务器设置为不侦听创建,则QWebSocket客户端不连接到QWebSocketServer;如果服务器稍后开始侦听,则不连接

文本溢出了Kivy的视区