为何break命令无法让多线程数字查找程序停止运行?
线程找到目标数字后程序未停止的原因及解决方法
问题描述
你编写了三个线程分别在不同数字区间内查找输入的数字,当某个线程找到目标数字并执行break后,程序并未停止,而是继续运行其他线程的循环。代码如下:
import threading import time def thread_func_1(): for i in range(1000,3334): time.sleep(0.02) print(f"thred1 {i}") if number == i: print(f"1.. Thread şifreyi buldu: {i}") break def thread_func_2(): for i in range(3334,6667): time.sleep(0.02) print(f"thred2 {i}") if number == i: print(f"2. Thread şifreyi buldu: {i}") break def thread_func_3(): for i in range(6667,10000): time.sleep(0.02) print(f"thred3 {i}") if number == i: print(f"3. Thread şifreyi buldu: {i}") break print("Lütfen bir sayı giriniz: ") number = int(input()) t1 = threading.Thread(target=thread_func_1) t2 = threading.Thread(target=thread_func_2) t3 = threading.Thread(target=thread_func_3) t1.start() t2.start() t3.start()
原因分析
break语句只能终止当前线程内的for循环,让执行该语句的线程结束,但无法影响其他正在运行的线程。- Python程序默认会等待所有非守护线程执行完毕后才会退出。你启动的三个线程都是非守护线程,所以即使其中一个线程结束,另外两个线程仍会继续执行循环,导致程序无法停止。
解决方法
方法1:使用全局标志位控制线程退出
定义一个全局变量作为停止标志,每个线程在循环时检查该标志,一旦标志为True就终止循环:
import threading import time # 全局停止标志 stop_flag = False def thread_func_1(): global stop_flag for i in range(1000,3334): if stop_flag: break time.sleep(0.02) print(f"thred1 {i}") if number == i: print(f"1.. Thread şifreyi buldu: {i}") stop_flag = True break def thread_func_2(): global stop_flag for i in range(3334,6667): if stop_flag: break time.sleep(0.02) print(f"thred2 {i}") if number == i: print(f"2. Thread şifreyi buldu: {i}") stop_flag = True break def thread_func_3(): global stop_flag for i in range(6667,10000): if stop_flag: break time.sleep(0.02) print(f"thred3 {i}") if number == i: print(f"3. Thread şifreyi buldu: {i}") stop_flag = True break print("Lütfen bir sayı giriniz: ") number = int(input()) t1 = threading.Thread(target=thread_func_1) t2 = threading.Thread(target=thread_func_2) t3 = threading.Thread(target=thread_func_3) t1.start() t2.start() t3.start()
方法2:使用threading.Event实现线程间通信
Event是线程安全的通信机制,比全局变量更可靠:
import threading import time # 创建事件对象 stop_event = threading.Event() def thread_func_1(): for i in range(1000,3334): if stop_event.is_set(): break time.sleep(0.02) print(f"thred1 {i}") if number == i: print(f"1.. Thread şifreyi buldu: {i}") stop_event.set() break def thread_func_2(): for i in range(3334,6667): if stop_event.is_set(): break time.sleep(0.02) print(f"thred2 {i}") if number == i: print(f"2. Thread şifreyi buldu: {i}") stop_event.set() break def thread_func_3(): for i in range(6667,10000): if stop_event.is_set(): break time.sleep(0.02) print(f"thred3 {i}") if number == i: print(f"3. Thread şifreyi buldu: {i}") stop_event.set() break print("Lütfen bir sayı giriniz: ") number = int(input()) t1 = threading.Thread(target=thread_func_1) t2 = threading.Thread(target=thread_func_2) t3 = threading.Thread(target=thread_func_3) t1.start() t2.start() t3.start()
方法3:设置守护线程(不推荐)
把线程设为守护线程,这样主线程结束时会强制终止所有守护线程。但这种方式可能导致线程未完成清理工作就被终止,仅适用于不需要优雅退出的场景:
# ... 前面函数代码不变 ... t1 = threading.Thread(target=thread_func_1, daemon=True) t2 = threading.Thread(target=thread_func_2, daemon=True) t3 = threading.Thread(target=thread_func_3, daemon=True) t1.start() t2.start() t3.start() # 主线程等待任意一个线程结束后退出 t1.join() t2.join() t3.join()
内容的提问来源于stack exchange,提问作者Fatih
相关产品推荐
相关产品推荐

