异步等待子处理?
Posted
技术标签:
【中文标题】异步等待子处理?【英文标题】:Asynchronous waiting with subprocessing? 【发布时间】:2022-01-02 08:55:43 【问题描述】:我在 Tkinter 脚本中有一个函数,它利用 subprocess.Popen.wait()
一直冻结我的 GUI。在浏览了一些文档(1 和2)之后,我发现我需要使用asyncio
通过异步等待来解决这个问题,但我很困惑:
注意:该函数是使用忙循环(非阻塞调用)实现的 和短暂的睡眠)。使用 asyncio 模块进行异步等待: 请参阅 asyncio.create_subprocess_exec。
这是否意味着我必须为我的 wait() 函数创建一个子进程?
另外,这是我目前所拥有的:
def foo(self)
try:
self.proc = subprocess.Popen(["python", "someModule.py"])
try:
self.proc.wait(11) # <-- freezes GUI
except Exception as l:
someFunc()
except Exception as e:
print(e)
注意:wait() 上的 TimeoutException 捕获用作另一个函数开始执行的指示符,而 wait() 的成功执行(即返回值 0)则相反。此外,我的目标是在成功执行子进程时激活我的 Tkinter 脚本中的计时器,如前所述,由 TimeoutException 指示。 Tkinter 接口将始终运行,而子进程将仅在用户输入时启动,并且类似地,在用户输入时结束(或者如果它意外崩溃)。
编辑:someModule.py
是一个脚本,用于激活外部数据采集蓝牙设备。它必须 (1) 建立与设备的连接,如果 (1) 成功,则 (2) 开始收集数据。功能 (1) 将等待 10 秒以建立与蓝牙设备的连接。如果 10 秒后没有建立连接,someModule.py
(即子进程)会打印错误并终止。这就是 wait() 执行 11 秒的原因。
如何实现异步等待?
【问题讨论】:
等待块,是的。相反应该发生什么?当进程运行/终止时你想发生什么? 你是否尝试在线程中执行foo()
?
@john-hen 感谢您的反馈。我不太确定我完全理解你的意思;您是说总是会执行 except 块,还是说我应该指定 TimeoutExpired 作为要捕获的异常?如果是前者,则不正确,因为当 wait() 的返回值为 0(零)时,不进入 except 块。
@MaxNoe 查看编辑。
tkinter
是不同于 asyncio
的异步“种类”。不能直接将两者一起使用。您必须编写自己的繁忙循环,使用tkinter
的睡眠方式。
【参考方案1】:
解决方法:通过thread 执行 foo() 解决了 GUI 冻结问题。
import threading
def thread(self):
t1 = threading.Thread(target=foo)
t1.start() # will terminate independently upon completion of foo()
【讨论】:
以上是关于异步等待子处理?的主要内容,如果未能解决你的问题,请参考以下文章