Python线程执行顺序异常,如何让指定线程执行完再执行后续逻辑?
Python线程同步问题
最近学习Python线程时遇到如下问题:需要让线程中的one函数执行完毕后,再执行two函数的收尾逻辑(打印'func two finished'),但join方法无法生效,显然是three函数中的while True循环导致的,尝试使用queue也没有效果。
原代码
from threading import Thread,Event import time def one(): event.set() thr.join() for i in range(3): print('some print') time.sleep(1) def two(): t = Thread(target=one) t.start() #with t.join() here the program does not work at all, same thing with event.set() print('func two finished') def three(callback, event): c = 0 while True: c += 1 time.sleep(1) print('func 3 is working') if c == 5: two() if event.is_set(): callback(c) print('func 3 is stopped') break def callback(t): print('callback ',t) def thread(callback): global event, thr event = Event() thr = Thread(target=three, args=(callback, event,)) thr.start() thr.join() thread(callback)
当前输出
func 3 is working func 3 is working func 3 is working func 3 is working func 3 is working func two finished callback 5 func 3 is stopped some print some print some print
期望输出
func 3 is working func 3 is working func 3 is working func 3 is working func 3 is working callback 5 func 3 is stopped some print some print some print func two finished
问题修复
核心问题分析
one函数中调用thr.join()会触发死锁:thr是three所在的线程,此时three仍在运行,one等待它结束,three又在等待event触发,形成互相阻塞。two函数启动one线程后直接打印收尾信息,没有等待one执行完毕,导致收尾信息提前输出。- 全局变量
thr的冗余使用增加了线程间的耦合和出错概率。
修复后的代码
import time from threading import Thread, Event def one(event): event.set() # 通知three线程退出 for i in range(3): print('some print') time.sleep(1) def two(): t = Thread(target=one, args=(event,)) t.start() t.join() # 等待one线程执行完毕后再打印收尾 print('func two finished') def three(callback, event): c = 0 while True: c += 1 time.sleep(1) print('func 3 is working') if c == 5: two() if event.is_set(): callback(c) print('func 3 is stopped') break def callback(t): print('callback ', t) def thread(callback): global event event = Event() thr = Thread(target=three, args=(callback, event,)) thr.start() thr.join() thread(callback)
关键改动说明
- 移除
one中错误的thr.join()调用,消除死锁隐患。 - 在
two中对one对应的线程调用t.join(),确保one执行完毕后再输出收尾信息。 - 删除全局变量
thr的冗余定义,简化线程间的引用关系。
运行修复后的代码,输出顺序将与期望完全一致。
内容的提问来源于stack exchange,提问作者Аким
相关产品推荐
相关产品推荐

