在python-telegram-bot中使用asyncio结合线程实现并发限制的技术咨询
在python-telegram-bot中使用asyncio结合线程实现并发限制的技术咨询
嘿,针对Telegram机器人里处理PDF生成这类耗时任务时的并发控制问题,我整理了一套实用的实现方案——既能保证任务高效执行,又不会让服务资源被过度占用,咱们一步步来看:
1. 先搞定并发上限的核心控制
首先得设定一个并发执行的最大数量,这里用asyncio.Semaphore来做限制,比如设置成3,意思就是同一时间最多允许3个PDF生成任务同时运行:
concurrency_limit = 3 semaphore = asyncio.Semaphore(concurrency_limit)
2. 核心异步处理函数的实现
接下来是处理用户请求的核心异步函数send_pdf,咱们用async with semaphore:来包裹任务逻辑,这样就能自动控制并发数了:
async def send_pdf(last_update: Update, context: ContextTypes.DEFAULT_TYPE): async with semaphore: chat_id = last_update.effective_chat.id msg = last_update.effective_message.text html_path = f"{HTML_PATH}/{msg}{chat_id}.html" pdf_path = f"{PDF_PATH}/{msg}{chat_id}{msg}.pdf" json_path = f"{JSON_PATH}/{msg}{chat_id}{msg}.json" # 先给用户发个提示,告诉他们任务启动了 await context.bot.send_message( chat_id=chat_id, text="يتم البحث عن الوظائف قد يستغرق الوقت دقيقتين ..." ) # 把阻塞的同步脚本放到线程里执行,别卡主整个异步循环 loop = asyncio.get_running_loop() data = await loop.run_in_executor(None, run_wuzzuf_script, msg) # 再给用户发个进度提示 await context.bot.send_message( chat_id=chat_id, text="جاري انشاء ملف الpdf الخاص بك" ) await asyncio.sleep(3) # 这里可以继续补充PDF生成的后续逻辑,比如根据拿到的data生成HTML、转成PDF等
3. 几个关键细节得注意
- 信号量的自动管理:
async with semaphore会帮咱们自动获取和释放信号量,不用手动操心。当任务数达到上限时,新的请求会自动排队,等前面的任务完成释放信号量后再执行。 - 阻塞代码的线程处理:像
run_wuzzuf_script这种同步阻塞的代码(比如爬虫、数据处理),直接放在异步函数里会卡住整个机器人的事件循环,用loop.run_in_executor把它丢到线程池里跑,就能保证机器人还能正常响应其他用户的请求。 - 用户体验优化:在任务的不同阶段给用户发提示消息,让用户清楚任务的进展,不会以为机器人没反应。
备注:内容来源于stack exchange,提问作者Eng.Ahmed
相关产品推荐
相关产品推荐

