请考虑以下代码:
import asyncio
sem: asyncio.Semaphore = asyncio.Semaphore(2)
async def async_run() -> None:
async def async_task() -> None:
async with sem:
await asyncio.sleep(1)
print('spam')
await asyncio.gather(*[async_task() for _ in range(3)])
asyncio.run(async_run())
运行在Python3.10.6(Fedora 35)上,它的工作原理就像教科书中的一样.
然而,当我使用Python3.8.10(Ubuntu 20.04)运行它时,我得到以下错误:
Traceback (most recent call last):
File "main.py", line 21, in <module>
asyncio.run(async_run())
File "/usr/lib/python3.8/asyncio/runners.py", line 44, 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 "main.py", line 18, in async_run
print(future_entry_index, await future_entry)
File "/usr/lib/python3.8/asyncio/tasks.py", line 619, in _wait_for_one
return f.result() # May raise f.exception().
File "main.py", line 11, in async_task
async with sem:
File "/usr/lib/python3.8/asyncio/locks.py", line 97, in __aenter__
await self.acquire()
File "/usr/lib/python3.8/asyncio/locks.py", line 496, in acquire
await fut
RuntimeError: Task <Task pending name='Task-4' coro=<async_run.<locals>.async_task() running at main.py:11> cb=[as_completed.<locals>._on_completion() at /usr/lib/python3.8/asyncio/tasks.py:606]> got Future <Future pending> attached to a different loop
导致错误的是async with sem
行和Semaphore
对象.如果没有它,一切都可以正常工作,但不是我想要的方式.
我不能在任何地方提供loop
参数,因为即使在允许的地方,它也从Python3.8开始就被弃用了,并在Python3.10中被删除了.
如何让代码在Python3.8上运行?
Update.瞥一眼asyncio
代码就会发现,这两个版本的Python有很大的不同.然而,信号量不能只在3.8中被打破,对吗?