首先,我需要警告你,我是新来的asyncio,而且我很讨厌使用asyncio.wait_for和asyncio.Semaphore。我是新来的asyncio, 我马上警告你, 我是新来的asyncio, 我很难想象库里的东西是什么.
这是我的代码。
import asyncio
semaphore = asyncio.Semaphore(50)
async def work(value):
async with semaphore:
print(value)
await asyncio.sleep(10)
async def main():
tasks = []
for i in range(0, 10000):
tasks.append(asyncio.wait_for(work(i), timeout=3))
await asyncio.gather(*tasks)
loop = asyncio.get_event_loop()
future = asyncio.ensure_future(main())
loop.run_until_complete(future)
我需要的是: Coroutine work()完成的时间不超过3秒 同时完成的数量不超过50件。3秒后(超时),coroutine work()必须停止执行,新的50个任务必须开始工作。但在我的情况下,3秒后就崩溃了。
Traceback (most recent call last):
File "C:/Users/root/PycharmProjects/LogParser/ssh/async/asyn_test.py", line 19, in <module>
loop.run_until_complete(future)
File "C:\Code\Python3\lib\asyncio\base_events.py", line 579, in run_until_complete
return future.result()
File "C:/Users/root/PycharmProjects/LogParser/ssh/async/asyn_test.py", line 15, in main
await asyncio.gather(*tasks)
File "C:\Code\Python3\lib\asyncio\tasks.py", line 449, in wait_for
raise futures.TimeoutError()
concurrent.futures._base.TimeoutError
不管我有没有尝试抓住这个异常,不管还有多少任务,程序都会崩溃。我需要,达到超时后,程序继续到下一个任务,请教我,我需要如何正确地实现这一点?
Python 3.7,asyncio 3.4.3。
你需要处理异常。如果你只是把它传给 gather
,它将重新提起它。例如,你可以用适当的tryexcept创建一个新的coroutine。
semaphore = asyncio.Semaphore(50)
async def work(value):
print(value)
await asyncio.sleep(10)
async def work_with_timeout(value):
async with semaphore:
try:
return await asyncio.wait_for(work(value), timeout=3)
except asyncio.TimeoutError:
return None
async def main():
tasks = []
for i in range(0, 10000):
tasks.append(work_with_timeout(i))
await asyncio.gather(*tasks)