gpt4 book ai didi

python - 关闭前冲洗管道 (os.pipe)

转载 作者:太空宇宙 更新时间:2023-11-04 01:13:57 37 4
gpt4 key购买 nike

我需要启动一个子进程并启用两个线程来分别读取它的 stdoutstderr

下面的代码只是考虑stdout:

def reader(rfd):
while True:
try:
data = os.read(rfd, bufsize)
except OSError:
break
else:
chomp(data)

rout, wout = os.pipe()
tout = threading.Thread(target=reader, args=(rout,))
tout.start()

subprocess.check_call(command, bufsize=bufsize, stdout=wout, stderr=werr)

os.close(wout)
os.close(rout)
tout.join()

代码有效,但我注意到并非所有数据都已处理,就好像 os.close(wout) 函数在读取所有数据之前 杀死了读取器。另一方面,如果我不关闭 wout,我的进程将永远卡在 tout.join() 上。

我可以看出这是一个缓冲问题,因为如果我在 subprocess.check_call(...) 之后放置一个非常糟糕的 time.sleep(0.1) 一切都会神奇地发生有效。

好的方法是刷新而不是等待,但是通过管道调用 os.fsync() 会给出 OSError: [Errno 22] Invalid argument

关于如何刷新使用 os.pipe 创建的管道的任何提示?

最佳答案

我建议使用 Popen 而不是 os.pipe 进行进程间通信。

例如。

writer_process = subprocess.Popen(cmd, stdout=subprocess.PIPE)
reader_thread = threading.Thread(target=reader, args=(writer_process.stdout,))
reader_thread.start()
reader_thread.join()

但是,如果您真的想使用 os.pipe,那么您将更容易将它们视为文件对象。 Python 的内置文件上下文管理器将确保文件正确刷新和关闭。

例如。

def reader(fd):
with os.fdopen(fd, bufsize=bufsize) as f:
while True:
data = f.read(bufsize)
if not data:
break
chomp(data)

with os.fdopen(wout, "w", bufsize=bufsize) as f:
subprocess.check_call(cmd, stdout=f)

关于python - 关闭前冲洗管道 (os.pipe),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25866092/

37 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com