python基础 多线程threading join 守护线程setDeamon 递归锁Rlock
Posted flag_HW
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python基础 多线程threading join 守护线程setDeamon 递归锁Rlock相关的知识,希望对你有一定的参考价值。
开篇大概介绍多线程与多进程区别,详细的理论区别自己可以在其它博客搜一下,这里不再赘述
同一进程下的多个线程共享内存数据,多个线程之间没有主次关系,相互之间可以操作;cpu执行的都是线程,默认程序会开一个主线程;进程是程序以及和程序相关资源的集合;某些场景下我们可以使用多线程来达到提高程序执行效率的目的,下面就多线程的一些基础知识做简要说明
简单的多线程
1 import threading, time 2 3 def test1(x): 4 time.sleep(5) 5 print(x**x) 6 7 #下面定义两个线程调用test1这个函数,创建多线程使用如下语法,target后面跟函数名,args传递实参,实参需要以元组形式传递 8 start_time = time.time() 9 t1 = threading.Thread(target=test1, args=(5,)) 10 t2 = threading.Thread(target=test1, args=(6,)) 11 #启动多线程 12 t1.start() 13 t2.start() 14 end_time = time.time() 15 total_time = end_time - start_time 16 print("two Thread used %s time"%total_time) #由于使用多线程,t1 t2启动以后并不会等待期执行完程序才继续往后走,因为主程序就是主线程和t1 t2是并行执行的,主程序执行到此t1 t2并未运行完成 17 18 time.sleep(6) 19 #多线程启动数量比较多时可以使用for循环,多线程并行执行,打印的结果有可能不是按照启动顺序来打印的 20 for i in range(5): 21 t3 = threading.Thread(target=test1, args=(i,)) 22 t3.start() 23 time.sleep(6)
主线程等待非主线程执行完毕才继续执行 join方法
1 #有些情况主线程需要子线程执行完毕后,有可能是将数据处理完毕后才执行接下来的主线程的东西 2 start_time1 = time.time() 3 tl = [] #将多线程的对象存起来,用于后面join方法 4 for i in range(5): 5 t4 = threading.Thread(target=test1, args=(i,)) 6 t4.start() 7 tl.append(t4) 8 for t in tl: #将多线程并发join,参加join的子线程执行完毕后才继续执行下面的主线程。 9 t.join() 10 end_time1 = time.time() 11 total_time1 = end_time1 - start_time1 12 print(total_time1) #此次执行时间大约就是5s
1 #如果多个子线程一些join一些没有join主线程怎么处理???部分子线程join主线程会等join时间最长的子线程结束后才继续,未参与join的子线程仍然和主线程并行运行 2 t5 = threading.Thread(target=test1, args=(5,)) 3 t6 = threading.Thread(target=test1, args=(6,)) 4 t5.start() 5 t6.start() 6 t5_join_start_time = time.time() 7 t5.join() 8 time.sleep(10) 9 t5_join_end_time = time.time() 10 print("t5 join time is %s"%(t5_join_end_time - t5_join_start_time)) #实际耗时15s
守护线程 setDeamon
1 #守护进程,即主线程结束以后所有的其它线程也立即结束,不用等其它线程执行完毕;正常情况即使没加join主线程执行完毕当其它线程未执行完毕程序也不会退出,必须等待所有线程执行完毕程序才结束,类似主程序在末尾有默认的join 2 def test1(x): 3 time.sleep(5) 4 print("i an other Thread",x**x) 5 6 for i in range(5): 7 t = threading.Thread(target=test1, args=(i,)) 8 t.setDaemon(True) 9 t.start() 10 11 print("Main Thread is done") #整个程序结束,不会等待守护线程打印操作执行完毕就直接结束了
递归锁 Rlock
1 #递归锁,一个锁里面嵌套着锁,如果不使用递归锁会导致释放锁逻辑错误,整个程序就跑偏了;使用递归锁后程序会维护一个加锁 解锁的数据结构,保证释放锁不会出问题 2 lock = threading.Lock() 3 def test2(): 4 lock.acquire() 5 print("this is test2") 6 lock.release() 7 8 def test3(): 9 lock.acquire() 10 print("this is test3") 11 lock.release() 12 13 def test4(): 14 lock.acquire() 15 test2() 16 print("this is test4") 17 test3() 18 lock.release() 19 20 rlock_test = threading.Thread(target=test4) 21 rlock_test.start() 22 23 while threading.active_count() != 1: 24 print("current thread count is",threading.active_count()) #整个程序一直在打印有两个线程,非主线程的锁嵌套出问题导致无法退出,整个程序卡死 25 time.sleep(1)
将lock = threading.Lock()修改为lock = threading.RLock()整个程序就能正常结束;正常结束的输出如下
this is test2
this is test4
current thread count is 2
this is test3
以上是关于python基础 多线程threading join 守护线程setDeamon 递归锁Rlock的主要内容,如果未能解决你的问题,请参考以下文章