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

Telegram Bot多用户同时执行cmd_2命令时冻结的问题求助

Telegram Bot多用户同时执行cmd_2命令时冻结的问题求助

嘿,我来帮你搞定这个问题!你的bot之所以在多用户用cmd_2时冻结,核心原因很简单:你的代码是单线程运行的,而cmd_2里的time.sleep(60)会彻底阻塞整个线程。

当第一个用户触发cmd_2后,这个函数会进入一个循环,每次暂停一分钟,整个bot的主线程都被这个循环占死了,根本腾不出时间处理其他用户的任何请求——直到这个循环跑完(5次sleep,也就是5分钟),或者程序中断,不然其他用户的命令都得不到响应。

解决方案:用多线程拆分耗时任务

我们可以把cmd_2里的循环sleep操作放到单独的线程里执行,这样主线程就能继续处理其他用户的请求了。具体修改步骤如下:

  1. 首先导入Python的threading模块,用来创建新线程
  2. 把cmd_2里的耗时逻辑抽成独立函数,让每个用户的任务在单独线程中运行
  3. 给cmd_2的处理函数加个用户存在性判断,避免KeyError

修改后的完整代码如下:

import telebot
import datetime
import time
import threading  # 新增:导入线程模块

API_TOKEN = "API_TOKEN"
bot = telebot.TeleBot(API_TOKEN)

user_dict = {}

class User:
    def __init__(self, name):
        self.name = name

# Handle '/start'
@bot.message_handler(commands=['start'])
def send_welcome(message):
    bot.reply_to(message, 'Hi there, I am Example bot.')

@bot.message_handler(commands=['cmd_1'])
def send_welcome(message):
    msg = bot.reply_to(message, "What's your name?")
    bot.register_next_step_handler(msg, process_name_step)

def process_name_step(message):
    try:
        chat_id = message.chat.id
        name = message.text
        user = User(name)
        user_dict[chat_id] = user
        bot.send_message(chat_id, 'Nice to meet you ' + user.name)
    except Exception as e:
        bot.reply_to(message, 'oooops')

@bot.message_handler(commands=['cmd_2'])
def cmd_2_handler(message):
    chat_id = message.chat.id
    # 新增:先判断用户是否已完成cmd_1设置,避免KeyError
    if chat_id not in user_dict:
        bot.send_message(chat_id, "请先执行/start和/cmd_1设置你的名字哦!")
        return
    user = user_dict[chat_id]
    # 新增:启动独立线程处理耗时任务
    threading.Thread(target=run_cmd_2_task, args=(chat_id, user.name), daemon=True).start()

# 新增:抽离耗时逻辑到独立函数
def run_cmd_2_task(chat_id, username):
    st = datetime.datetime.now()
    for i in range(5):
        sp = datetime.datetime.now()
        delta = sp - st
        # 优化:把timedelta转换成直观的分钟数(保留两位小数)
        minutes_passed = round(delta.total_seconds() / 60, 2)
        msg = f"{username}, 已经过去了{minutes_passed}分钟"
        bot.send_message(chat_id, msg)
        time.sleep(60)

bot.polling()

为什么这样改能解决问题?

  • 每个用户触发cmd_2时,都会开启一个独立的后台线程来执行循环和sleep操作,不会占用bot的主线程
  • 主线程可以继续监听和处理其他用户的命令请求,实现多用户同时使用bot的需求
  • daemon=True参数确保这些后台线程会随bot主程序的退出而自动结束,不会残留无用线程

备注:内容来源于stack exchange,提问作者Luigi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.20 11:34:31