You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用asyncio模拟CPU时钟时的并行运行问题求助

问题分析与解决方案

核心问题

你的代码有两个关键问题导致无法正常并行运行:

  1. 事件循环提前退出:main函数创建了时钟和CPU的异步任务,但没有等待任务完成,asyncio.run(main())会在main执行完毕后直接关闭事件循环,两个任务还没真正运行就被终止。
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 12:50:23