Python多线程threading join和守护线程setDeamon原理详解
本文深入解析Python多线程核心机制。通过代码示例演示threading模块中join方法如何阻塞主线程等待子线程完成,以及setDaemon将子线程设为守护线程以实现主线程退出时强制结束子线程的行为。此外,重点讲解递归锁RLock解决死锁问题的原理,对比普通Lock在嵌套调用中的缺陷,确保多线程程序稳定运行。
Python多线程基础与共享内存机制
在同一进程内,多个线程共享相同的内存数据空间,线程之间不存在主次之分,彼此可以相互操作。CPU实际执行的是线程任务,程序默认会启动一个主线程。进程则是程序代码及其相关资源的集合体。在某些特定场景下,利用多线程技术可以有效提升程序的执行效率。接下来将对多线程的基础知识进行简要说明。
简单的多线程实现示例
多线程的基本创建与并行执行
import threading, time
def test1(x):
time.sleep(5)
print(x**x)
#下面定义两个线程调用test1这个函数,创建多线程使用如下语法,target后面跟函数名,args传递实参,实参需要以元组形式传递
start_time = time.time()
t1 = threading.Thread(target=test1, args=(5,))
t2 = threading.Thread(target=test1, args=(6,))
#启动多线程
t1.start()
t2.start()
end_time = time.time()
total_time = end_time - start_time
print("two Thread used %s time"%total_time) #由于使用多线程,t1 t2启动以后并不会等待期执行完程序才继续往后走,因为主程序就是主线程和t1 t2是并行执行的,主程序执行到此t1 t2并未运行完成
time.sleep(6)
#多线程启动数量比较多时可以使用for循环,多线程并行执行,打印的结果有可能不是按照启动顺序来打印的
for i in range(5):
t3 = threading.Thread(target=test1, args=(i,))
t3.start()
time.sleep(6)
主线程等待非主线程执行完毕才继续执行 join方法
使用join方法同步主线程与子线程
#有些情况主线程需要子线程执行完毕后,有可能是将数据处理完毕后才执行接下来的主线程的东西
start_time1 = time.time()
tl = [] #将多线程的对象存起来,用于后面join方法
for i in range(5):
t4 = threading.Thread(target=test1, args=(i,))
t4.start()
tl.append(t4)
for t in tl: #将多线程并发join,参加join的子线程执行完毕后才继续执行下面的主线程。
t.join()
end_time1 = time.time()
total_time1 = end_time1 - start_time1
print(total_time1) #此次执行时间大约就是5s
混合使用join与未join线程的执行时序
#如果多个子线程一些join一些没有join主线程怎么处理???部分子线程join主线程会等join时间最长的子线程结束后才继续,未参与join的子线程仍然和主线程并行运行
t5 = threading.Thread(target=test1, args=(5,))
t6 = threading.Thread(target=test1, args=(6,))
t5.start()
t6.start()
t5_join_start_time = time.time()
t5.join()
time.sleep(10)
t5_join_end_time = time.time()
print("t5 join time is %s"%(t5_join_end_time - t5_join_start_time)) #实际耗时15s
守护线程 setDeamon
守护线程setDaemon的生命周期管理
#守护进程,即主线程结束以后所有的其它线程也立即结束,不用等其它线程执行完毕;正常情况即使没加join主线程执行完毕当其它线程未执行完毕程序也不会退出,必须等待所有线程执行完毕程序才结束,类似主程序在末尾有默认的join
def test1(x):
time.sleep(5)
print("i an other Thread",x**x)
for i in range(5):
t = threading.Thread(target=test1, args=(i,))
t.setDaemon(True)
t.start()
print("Main Thread is done") #整个程序结束,不会等待守护线程打印操作执行完毕就直接结束了
递归锁 Rlock
递归锁RLock解决嵌套死锁问题
#递归锁,一个锁里面嵌套着锁,如果不使用递归锁会导致释放锁逻辑错误,整个程序就跑偏了;使用递归锁后程序会维护一个加锁 解锁的数据结构,保证释放锁不会出问题
lock = threading.Lock()
def test2():
lock.acquire()
print("this is test2")
lock.release()
def test3():
lock.acquire()
print("this is test3")
lock.release()
def test4():
lock.acquire()
test2()
print("this is test4")
test3()
lock.release()
rlock_test = threading.Thread(target=test4)
rlock_test.start()
while threading.active_count() != 1:
print("current thread count is",threading.active_count()) #整个程序一直在打印有两个线程,非主线程的锁嵌套出问题导致无法退出,整个程序卡死
time.sleep(1)
将lock = threading.Lock()修改为lock = threading.RLock()整个程序就能正常结束;正常结束的输出如下
this is test2 this is test4 current thread count is 2 this is test3
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













