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

Python Asyncio:为何两个无限循环异步函数无法并发运行?

问题根源

你的代码里的_wait_new_file和_check_difference是同步阻塞的无限循环,完全霸占了asyncio的单线程事件循环,导致第二个任务根本没机会被调度执行。

asyncio的事件循环依赖任务主动让出CPU(通过await异步操作)来实现并发。而你的两个_sync方法里是纯同步的死循环,没有任何await语句或让出控制权的逻辑,一旦第一个任务启动,就会一直占用事件循环,其他任务永远得不到运行机会。

修复方案

核心是把同步循环改成异步循环,在每次循环中加入await asyncio.sleep(xxx)让出CPU,同时优化文件操作逻辑:

import asyncio
import os


class Program:
    def __init__(self):
        self.files = set(os.listdir('data'))  # 用集合替代列表,集合差集运算更高效
        self.last_file = ''
        self.history = []

    async def wait_new_file(self):
        await self._wait_new_file()

    async def _wait_new_file(self):  # 改为异步方法
        while True:
            checked_files = set(os.listdir('data'))
            # 处理新增文件
            if new_files := checked_files - self.files:
                for new_file in new_files:
                    print(f'{new_file = }')
                    self.last_file = new_file
                    self.files.add(new_file)
                    self.history.append(f'>>> {new_file}')
                print(f'{self.files = }')
            # 处理删除文件
            if deleted_files := self.files - checked_files:
                for deleted_file in deleted_files:
                    print(f'{deleted_file = }')
                    self.files.remove(deleted_file)
                print(f'{self.files = }')
            # 终止条件
            if os.path.exists('stop'):
                print(self.history)
                return
            await asyncio.sleep(0.1)  # 让出CPU,让其他任务执行

    async def check_difference(self):
        await self._check_difference()

    async def _check_difference(self):  # 改为异步方法
        flip = True
        while True:
            current_exists = os.path.exists('flip')
            if flip and current_exists:
                flip = False
                print('on')
            elif not flip and not current_exists:
                flip = True
                print('off')
            # 终止条件
            if os.path.exists('stop'):
                return
            await asyncio.sleep(0.1)  # 让出CPU

    async def main(self):
        async with asyncio.TaskGroup() as tg:
            task_check_difference = tg.create_task(self.check_difference())
            task_monitor_files = tg.create_task(self.wait_new_file())

program = Program()
asyncio.run(program.main())
关键修改点
  1. 将两个_sync方法改为异步方法(添加async关键字)
  2. 在每个循环末尾加入await asyncio.sleep(0.1):这是实现并发的核心,它会让当前任务暂停,把控制权交还给事件循环,让其他任务有机会执行,同时也避免高频轮询消耗资源
  3. 将self.files从列表改为集合,优化文件差集运算的效率,同时避免重复添加文件
  4. 优化了多文件新增/删除的处理逻辑(原来的代码只处理单个文件)

内容的提问来源于stack exchange,提问作者youjin1985

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 20:12:43