Python - 为什么我的超时异常总是执行



我正在尝试掌握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完成后立即引发异常。向toastercreate添加一些打印显示三个任务已完成,因此执行仅以 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 ...?我会说你写它是为了这样做——看起来这就是你的意图。

相关内容

  • 没有找到相关文章

最新更新