Python asyncio:在工作线程上运行subprocess_exec
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Python asyncio:在工作线程上运行subprocess_exec,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2503字,纯文字阅读大概需要4分钟。
内容图文
![Python asyncio:在工作线程上运行subprocess_exec](/upload/InfoBanner/zyjiaocheng/822/dfa79a2f9f6e4f2d9fd20384d7442b2e.jpg)
所以我使用Python asyncio模块(在Linux上)启动子进程,然后异步监视它.我的代码工作正常…在主线程上运行时.但是当我在工作线程上运行它时,它会挂起,并且永远不会调用process_exited回调.
我怀疑这可能实际上是某种未记录的缺陷或在工作线程上运行subprocess_exec的问题,可能与实现如何处理后台线程中的信号有关.但它也可能只是让我搞砸了.
一个简单,可重复的例子如下:
class MyProtocol(asyncio.SubprocessProtocol):
def __init__(self, done_future):
super().__init__()
self._done_future = done_future
def pipe_data_received(self, fd, data):
print("Received:", len(data))
def process_exited(self):
print("PROCESS EXITED!")
self._done_future.set_result(None)
def run(loop):
done_future = asyncio.Future(loop = loop)
transport = None
try:
transport, protocol = yield from loop.subprocess_exec(
lambda : MyProtocol(done_future),
"ls",
"-lh",
stdin = None
)
yield from done_future
finally:
if transport: transport.close()
return done_future.result()
def run_loop():
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop) # bind event loop to current thread
try:
return loop.run_until_complete(run(loop))
finally:
loop.close()
所以在这里,我设置了一个asyncio事件循环来执行shell命令ls -lh,然后触发从子进程接收数据时的回调,以及子进程退出时的另一个回调.
如果我只是直接在Python程序的主线程中调用run_loop(),一切都很顺利.但如果我说:
t = threading.Thread(target = run_loop)
t.start()
t.join()
然后会发生的事情是成功调用了pipe_data_received()回调,但是从不调用process_exited(),程序就会挂起.
在谷歌搜索并查看用于实现unix_events.py的asyncio源代码后,我发现可能需要手动将我的事件循环附加到全局“子监视器”对象,如下所示:
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop) # bind event loop to current thread
asyncio.get_child_watcher().attach_loop(loop)
显然,儿童观察者是一个(未记录的)对象,负责在引擎盖下调用waitpid(或类似的东西).但是当我尝试这个,并在后台线程中运行run_event_loop()时,我得到了错误:
File "/usr/lib/python3.4/asyncio/unix_events.py", line 77, in add_signal_handler
raise RuntimeError(str(exc))
RuntimeError: set_wakeup_fd only works in main thread
所以这看起来实现实际上做了检查以确保信号处理程序只能在主线程上使用,这使我相信在当前实现中,在后台线程上使用subprocess_exec实际上是根本不可能不改变Python源代码本身.
我对此是否正确?可悲的是,asyncio模块的记录很少,所以我很难对这里的结论充满信心.我可能只是做错了什么.
解决方法:
只要asyncio循环在主线程中运行并且子监视器实例化,就可以处理工作线程中的子进程:
asyncio.get_child_watcher()
loop = asyncio.get_event_loop()
coro = loop.run_in_executor(None, run_loop)
loop.run_until_complete(coro)
内容总结
以上是互联网集市为您收集整理的Python asyncio:在工作线程上运行subprocess_exec全部内容,希望文章能够帮你解决Python asyncio:在工作线程上运行subprocess_exec所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。