Python如何启动独立线程处理用户输入且不阻塞主线程?
问题修复与优化方案
原代码的核心问题
- 全局变量未正确引用:子线程
task函数中修改correction_in_degrees和correction_in_counts时,未声明为全局变量,导致实际修改的是函数内的局部变量,主线程始终读取初始值。 - 输出干扰输入:主线程和子线程的
print操作无同步机制,导致子线程的输入提示被主线程的打印内容打断,无法正常输入。
修复后的代码(Python 3版本)
from time import sleep from threading import Thread, Lock # 全局变量 correction_in_counts = 0 correction_in_degrees = 0 # 打印锁,避免输出混乱 print_lock = Lock() def task(): global correction_in_degrees, correction_in_counts while True: with print_lock: print("This is from the newly spawned thread.\n") # 单独获取输入,避免被其他线程打断 try: user_input = input("Enter correction (degrees): ") correction_in_degrees = int(user_input) correction_in_counts = int(correction_in_degrees * 5.6) with print_lock: print(f"I received: {correction_in_degrees}") print(f"I calculated: {correction_in_counts}\n") except ValueError: with print_lock: print("请输入有效的整数!\n") thread = Thread(target=task) thread.daemon = True thread.start() while True: with print_lock: print("-------------------------------") print("HERE I'm running the MAIN thread (thread0).") print(f"DEGREES received from TASK FUNCTION: {correction_in_degrees}") print(f"COUNTS received from TASK FUNCTION: {correction_in_counts}\n") sleep(1) # 模拟主线程的工作延迟,避免输出过于频繁
修复点说明
- 添加
global声明,让子线程可以修改全局变量。 - 使用
Lock对象同步打印操作,避免主线程和子线程的输出互相干扰,确保输入提示清晰可见。 - 增加异常处理,防止用户输入非整数导致程序崩溃。
- 主线程添加
sleep(1),模拟实际工作中的延迟,避免输出刷屏。
更规范的实现思路:使用队列传递数据
多线程中直接使用全局变量存在线程安全隐患(虽然本案例中是简单赋值,但复杂场景下可能出问题),更推荐使用queue.Queue来传递用户输入的数据:
from time import sleep from threading import Thread, Lock from queue import Queue input_queue = Queue() print_lock = Lock() def task(): while True: try: user_input = input("Enter correction (degrees): ") correction_in_degrees = int(user_input) correction_in_counts = int(correction_in_degrees * 5.6) # 将计算结果放入队列 input_queue.put((correction_in_degrees, correction_in_counts)) with print_lock: print(f"I received: {correction_in_degrees}") print(f"I calculated: {correction_in_counts}\n") except ValueError: with print_lock: print("请输入有效的整数!\n") thread = Thread(target=task) thread.daemon = True thread.start() # 主线程处理逻辑 correction_in_degrees = 0 correction_in_counts = 0 while True: # 检查队列是否有新数据 if not input_queue.empty(): correction_in_degrees, correction_in_counts = input_queue.get() with print_lock: print("-------------------------------") print("HERE I'm running the MAIN thread (thread0).") print(f"DEGREES received from TASK FUNCTION: {correction_in_degrees}") print(f"COUNTS received from TASK FUNCTION: {correction_in_counts}\n") sleep(1)
优势说明
- 队列是线程安全的,无需额外同步即可在多线程间传递数据。
- 避免了全局变量的使用,代码结构更清晰,耦合度更低。
内容的提问来源于stack exchange,提问作者luke
相关产品推荐
相关产品推荐

