ProcessPoolExecutor与Popen配合使用

 一直以为concurrent.futures.ThreadPoolExecutor()可以配合os.execlp(),然后并不行,os.execlp()是装载一个新的程序运行,而保持原来的pid不变,原来的stdout和stderr没有被保留到新程序,会出现如下错误:

concurrent.futures.process.BrokenProcessPool: A process in the process pool was terminated abruptly while the future was running or pending.

据说可以通过修改stdout和stderr属性达到获取输出。不过不管怎么样,更好的配合应该是concurrent.futures.ThreadPoolExecutor()和subprocess.Popen(),它新启一个进程,然后用io.open建立好pipe,特别是有cwd参数,也是非常有用。

举例:

from subprocess import Popen, PIPE, STDOUT

def jobs():
    with Popen(["ifconfig", '-badargs'], stdout=PIPE, stderr=STDOUT) as proc:
        print(proc.stdout.read().decode())

import asyncio
from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor

loop = asyncio.get_event_loop()

async def run():
    with ProcessPoolExecutor() as executor:
        await loop.run_in_executor(executor, jobs)

loop.run_until_complete(run())

这里将stderr的输出导入到stdout的pipe里,也可以各自建立一个pipe:

def jobs():
    with Popen(["ifconfig", '-badargs'], stdout=PIPE, stderr=PIPE) as proc:
        print(proc.stdout.read().decode())
        print(proc.stderr.read().decode())

with语法让关系文件,回收资源变成自动。

发表于 2020年07月11日 09:35   评论:0   阅读:4194  



回到顶部

首页 | 关于我 | 关于本站 | 站内留言 | rss
python logo   django logo   tornado logo