使用asyncio模拟CPU时钟时的并行运行问题求助
问题分析与解决方案
核心问题
你的代码有两个关键问题导致无法正常并行运行:
- 事件循环提前退出:
main函数创建了时钟和CPU的异步任务,但没有等待任务完成,asyncio.run(main())会在main执行完毕后直接关闭事件循环,两个任务还没真正运行就被终止。 - CPU重复执行:时钟高电平期间,CPU处理完任务后会立刻进入下一次循环,此时时钟事件仍处于
set状态,导致CPU在同一个时钟周期内重复执行,不符合“每个时钟上升沿执行一次”的预期。
修改后的代码
import asyncio class Clock: def __init__(self, frequency: int): if not isinstance(frequency, int) or frequency <= 0: raise ValueError('Frequency must be a positive integer.') self.frequency = frequency self.period = 1 / frequency self.half_period = self.period / 2 self._clock_pulse = asyncio.Event() async def run(self): while True: self._clock_pulse.set() print('high', self._clock_pulse.is_set()) await asyncio.sleep(self.half_period) self._clock_pulse.clear() print('low', self._clock_pulse.is_set()) await asyncio.sleep(self.half_period) async def schedule(self, func, *args): print('scheduled') # 等待时钟上升沿(事件被设置为高电平) await self._clock_pulse.wait() # 执行CPU任务 result = await func(*args) # 等待时钟回到低电平,确保下一次调度对应下一个周期的上升沿 while self._clock_pulse.is_set(): await asyncio.sleep(0) return result class CPU: def __init__(self, clock): self.clock = clock async def do_nothing(self, n): return n async def run(self): self.n = 0 while True: value = await self.clock.schedule(self.do_nothing, self.n) print(value) self.n += 1 clock = Clock(1) cpu = CPU(clock) async def main(): clock_task = asyncio.create_task(clock.run()) cpu_task = asyncio.create_task(cpu.run()) # 等待两个无限循环的任务(会一直运行直到手动终止) await asyncio.gather(clock_task, cpu_task) asyncio.run(main())
关键修改说明
- 修复事件循环退出问题:在
main函数中添加await asyncio.gather(clock_task, cpu_task),让事件循环持续运行直到两个任务被手动终止。 - 修正CPU执行逻辑:在
schedule方法中,执行完CPU任务后添加循环等待时钟回到低电平,确保下一次schedule会等待下一个时钟上升沿,避免同一个周期内重复执行。
关于多线程的疑问
你不需要使用多线程,asyncio的协程模型完全可以满足单线程内的并发需求。只要正确使用await让出执行权,事件循环会自动调度时钟和CPU任务交替运行,实现你需要的并行效果。
内容的提问来源于stack exchange,提问作者Ford03
相关产品推荐
相关产品推荐

