我正在尝试掌握Python的asyncio库,但我遇到了超时异常的问题。我不知道为什么"异步"。"async def create"函数中的 TimeoutError" 异常总是在我的程序结束时执行,即使超时限制尚未超过。感谢您的专家建议和意见:)
谢谢你的时间。
import asyncio
import multiprocessing as mp
from enum import Enum
class Sensor(Enum):
GREEN = 0
RED = 1
class State(Enum):
NORMAL = 0
MEDIUM = 1
BURNED = 2
class Toaster:
def __init__(self, min = 20, max = 50, temp = 0, timer = 0, state = State.NORMAL, sensor = Sensor.GREEN):
self.min = min
self.max = max
self.temp = self.min
self.timer = timer
self.state = state
self.sensor = sensor
def display(self):
print("nTimer state:", self.timer, "seconds")
print("Toast state:", self.state.name)
print("Sensor state:", self.sensor.name)
async def start(self):
while True:
if self.temp <= self.max:
await asyncio.sleep(0.1)
print("Temperature:", self.temp)
self.temp+=1
else:
print("nMaximum temperature", self.max, "celsius reached")
await self.measure_state()
await self.restart()
break
async def restart(self):
while True:
if self.temp >= self.min:
await asyncio.sleep(0.1)
print("Temperature:", self.temp)
self.temp-=1
else:
self.sensor = Sensor.GREEN
print("nMinimum temperature", self.min, "celsius reached")
break
async def validateInput(self, message):
valid = False
while not valid:
try:
userInput = int(input(message))
if userInput == 0 or userInput == 1:
valid = True
return userInput
else:
raise ValueError("nInvalid value", userInput)
except ValueError as v:
print(v)
async def eject(self):
self.display()
message = "nEject toast - 1(Yes), 0(No):"
try:
return await asyncio.wait_for(self.validateInput(message), timeout=1000)
except asyncio.TimeoutError:
print("Took too long - eject")
async def repeat(self):
message = "nInject another toast - 1(Yes), 0(No):"
try:
return await asyncio.wait_for(self.validateInput(message), timeout=1000)
except asyncio.TimeoutError:
print("Took too long - repeat")
async def measure_state(self):
while True:
await asyncio.sleep(5)
self.timer+=50
if self.timer == 50:
print("nToast is in it's", self.state.name, "state")
if await self.eject() == 1:
print("nToast ejected")
if await self.repeat() == 1:
self.timer = 0
self.state = State.NORMAL
await self.measure_state()
break
elif self.timer == 100:
self.state = State.MEDIUM
self.sensor = Sensor.RED
print("nToast is in it's", self.state.name, "state")
if await self.eject() == 1:
print("nToast ejected")
if await self.repeat() == 1:
self.timer = 0
self.state = State.NORMAL
await self.measure_state()
break
elif self.timer >= 150:
self.state = State.BURNED
print("nToast is in it's", self.state.name, "state, ejecting toast")
break
async def toaster(self):
message = "nInsert a toast - 1(Yes), 0(No):"
while await self.validateInput(message) != 1:
print("nPlease insert a toast")
print("nToast inserted")
await self.start()
async def create(self):
x = loop.create_task(Toaster().toaster())
y = loop.create_task(Toaster().toaster())
z = loop.create_task(Toaster().toaster())
try:
await asyncio.wait([x, y, z], timeout=1000)
raise asyncio.TimeoutError("nTook too long - create")
except asyncio.TimeoutError as t:
print(t)
x.cancel(), y.cancel(), z.cancel()
def get_process_count():
nproc = mp.cpu_count()
pool = mp.Pool(processes=nproc)
return pool
class Connector(Toaster):
pass
async def main():
connector = Connector()
result = get_process_count()
result.map(await connector.create())
await asyncio.gather(result)
if __name__ == "__main__":
loop = None
try:
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
except Exception as e:
pass
finally:
loop.close()
create()
在等待任务x,y,z
完成后立即引发异常。向toaster
和create
添加一些打印显示三个任务已完成,因此执行仅以 raise asyncio.TimeoutError...
语句恢复。
...
async def toaster(self):
message = "nInsert a toast - 1(Yes), 0(No):"
while await self.validateInput(message) != 1:
print("nPlease insert a toast")
print("nToast inserted")
await self.start()
return 'FINISHED'
async def create(self):
x = loop.create_task(Toaster().toaster())
y = loop.create_task(Toaster().toaster())
z = loop.create_task(Toaster().toaster())
try:
await asyncio.wait([x, y, z], timeout=1000)
for thing in (x,y,z):
print(thing)
raise asyncio.TimeoutError("nTook too long - create") # <-- you raise the exception Here!
except asyncio.TimeoutError as t:
print(t)
x.cancel(), y.cancel(), z.cancel()
结果在
>>>
...
...
Temperature: 20
Minimum temperature 20 celsius reached
Temperature: 20
Minimum temperature 20 celsius reached
Temperature: 20
Minimum temperature 20 celsius reached
<Task finished coro=<Toaster.toaster() done, defined at tmp.py:129> result='FINISHED'>
<Task finished coro=<Toaster.toaster() done, defined at tmp.py:129> result='FINISHED'>
<Task finished coro=<Toaster.toaster() done, defined at tmp.py:129> result='FINISHED'>
Took too long - create
- 我插入了 3 个吐司并在第一次要求时弹出它们。
- 我经历了十几个注射和喷射吐司的循环,但没有超时,但一旦拒绝注入,就会引发异常更多吐司。
...why does the "asyncio.TimeoutError" exception in the "async def create" function always execute at the end of my program ...?
我会说你写它是为了这样做——看起来这就是你的意图。