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

Python客户端-服务器问答游戏输入监听线程无法终止问题

问题分析

你的核心问题在于输入监听线程__input_listener是死循环,且input()是阻塞调用——即使外部把is_playing设为False,线程仍会卡在input()等待用户输入,无法响应终止信号,导致主线程的listener_thread.join()一直阻塞。

解决方案

给监听线程添加终止事件(threading.Event),同时用非阻塞方式监听输入,让线程能定期检查终止信号,具体修改如下:

修改监听线程函数

引入select模块实现带超时的输入监听,同时接收终止事件作为参数:

def __input_listener(self, input_queue, stop_event):
    import sys
    import select
    while not stop_event.is_set():
        # 每隔0.5秒检查一次stdin是否有输入,同时响应终止信号
        ready, _, _ = select.select([sys.stdin], [], [], 0.5)
        if ready:
            try:
                # 模拟input()的行为,读取一行并去掉末尾换行
                message = sys.stdin.readline().strip()
                if message:
                    input_queue.put(message)
            except EOFError:
                break

修改输入处理函数

创建终止事件并传给监听线程,在需要终止时触发事件:

def __handle_user_inputs(self):
    import threading
    input_queue = queue.Queue()
    stop_event = threading.Event()
    listener_thread = threading.Thread(target=self.__input_listener, args=(input_queue, stop_event))
    listener_thread.start()

    while self.is_alive and self.is_playing:
        try:
            message = input_queue.get(timeout=0.5)
            self.__send_message(message)
        except queue.Empty:
            if not self.is_playing:
                break

    # 通知监听线程终止
    stop_event.set()
    listener_thread.join()  # 线程会快速退出,不再阻塞
关键说明
  1. 终止事件(Event):作为线程间的安全通信机制,用来通知监听线程需要退出。
  2. 带超时的输入监听:用select.select()替代阻塞的input(),每隔0.5秒检查一次输入和终止信号,避免线程一直卡在等待输入的状态。
  3. 行为一致性:sys.stdin.readline().strip()和input()的行为一致,都会读取用户输入的一行并去掉末尾的换行符。

内容的提问来源于stack exchange,提问作者Gil Ari Agmon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 21:42:24