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

如何在Python aiogram3中将阻塞函数放入单独线程?

解决同步阻塞函数导致机器人无响应的方案

针对同步计算函数阻塞机器人事件循环的问题,可通过asyncio.run_in_executor()将阻塞函数放到单独线程执行,避免影响机器人处理其他请求。具体实现如下:

修改后的完整代码

import asyncio
from time import sleep
import logging
from concurrent.futures import ThreadPoolExecutor  # 导入线程池

from aiogram import Bot, Dispatcher, Router
from aiogram.filters import Command
from aiogram.types import Message


token = "<token>"

bot = Bot(token=token)
dispatcher = Dispatcher()
router = Router()
dispatcher.include_router(router)

# 初始化线程池(可选,不指定则用默认线程池)
executor = ThreadPoolExecutor(max_workers=4)


def block_function() -> str:
    sleep(2)
    return "Complete!"


@router.message(Command("start"))
async def start(message: Message) -> None:
    username = message.from_user.username
    await message.answer(f"Hello, {username}!")
    await message.answer("Start...")
    # 用run_in_executor将阻塞函数放到线程执行
    result = await asyncio.run_in_executor(executor, block_function)
    await message.answer(result)


@router.message(Command("escape"))
async def stop_polling(message: Message) -> None:
    await message.answer("Bye!")
    await dispatcher.stop_polling()
    executor.shutdown()  # 关闭线程池(程序结束时清理)


async def main() -> None:
    logging.basicConfig(level=logging.INFO)
    await dispatcher.start_polling(bot)


if __name__ == "__main__":
    asyncio.run(main())

关键说明

  • asyncio.run_in_executor()会把传入的同步函数提交到线程池执行,主事件循环可继续处理其他用户请求,不会被阻塞。
  • 显式初始化ThreadPoolExecutor可控制线程数量(比如根据计算任务的并发需求调整max_workers),若不指定第一个参数(传None),会使用asyncio默认的线程池。
  • 程序结束时需调用executor.shutdown()清理线程池资源,避免内存泄漏。

内容的提问来源于stack exchange,提问作者name 0x0000000F

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 09:02:20