如何解决在异步循环中调用os.fork时,设计行为是什么?
asyncio是否可以与os.fork()一起使用?
代码段1:
import asyncio
import os
import aiohttp
async def main():
url = "https://google.com"
pid = os.fork()
if pid == 0:
# child process
print("in child process")
await fetch(url)
print("in child process done")
else:
print("in parent process")
await asyncio.sleep(20)
print("in parent process done")
async def fetch(url):
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
return await response.text()
if __name__ == "__main__":
asyncio.run(main())
上面的代码可以正常工作。
代码段2:
import asyncio
import os
import aiohttp
async def main():
url = "https://google.com"
pid = os.fork()
if pid == 0:
# child process
print("in child process")
await asyncio.sleep(10) # different with code snippet 1
# await fetch(url)
print("in child process done")
else:
print("in parent process")
await asyncio.sleep(20)
print("in parent process done")
async def fetch(url):
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
return await response.text()
if __name__ == "__main__":
asyncio.run(main())
上面的代码将引发以下异常:
Traceback (most recent call last):
File "fork_sleep.py",line 28,in <module>
asyncio.run(main())
File "/usr/lib/python3.8/asyncio/runners.py",line 43,in run
return loop.run_until_complete(main)
File "/usr/lib/python3.8/asyncio/base_events.py",line 616,in run_until_complete
return future.result()
File "fork_sleep.py",line 13,in main
await asyncio.sleep(10) # different with code snippet 1
File "/usr/lib/python3.8/asyncio/tasks.py",line 637,in sleep
loop = events.get_running_loop()
RuntimeError: no running event loop
“没有运行事件循环”异常的原因是函数get_running_loop比较os.getpid()和保存在循环中的pid。如果它们不同,则会引发上面的异常。
请从cpython源代码中参考以下代码。
def get_running_loop():
"""Return the running event loop. Raise a RuntimeError if there is none.
This function is thread-specific.
"""
# NOTE: this function is implemented in C (see _asynciomodule.c)
loop = _get_running_loop()
if loop is None:
raise RuntimeError('no running event loop')
return loop
def _get_running_loop():
"""Return the running event loop or None.
This is a low-level function intended to be used by event loops.
This function is thread-specific.
"""
# NOTE: this function is implemented in C (see _asynciomodule.c)
running_loop,pid = _running_loop.loop_pid
if running_loop is not None and pid == os.getpid():
return running_loop
因此,如果您不触摸get_running_loop函数,则asyncio事件循环在子进程中似乎可以正常工作。 我的问题是,设计行为是什么?为什么作者检查函数_get_running_loop中的pid?如果在子进程中遇到“无运行事件循环”,那该怎么办?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。