day9 - 守护线程
一、概述
我们说在不加join的时候,主线程和子线程完全是并行的,没有了依赖关系,你主线程执行了,我子线程也执行了。但是加了join之后,主线程依赖子线程执行完毕才往下走。现在我们要把所有的子线程编程我的守护进程。
守护进程:说白了,你是主人,你搞了几个仆人,这些个仆人都是为你服务的。可以帮你做很多事情,一个主人可以有多个守护进程,它们为你服务的前提是,主线程必须存在,如果主线程不存在,则守护进程也没了。那守护进程是干嘛的呢?帮你管理一些资源,打开一些文件,监听一些端口,监听一些资源,把一些垃圾资源会后,它可以干很多事情,这些完全定义,你想干嘛干嘛。
二、知识补充
2.1、查看当前线程和统计活动线程个数
说明:用theading.current_thead()查看当前线程;用theading.active_count()来统计当前活动的线程数
1 import threading 2 import time 3 4 def run(n): 5 print("task",n) 6 time.sleep(2) #代表处理某个功能代码需要2秒 7 8 9 # t1= threading.Thread(target=run,args=("t1",)) 10 # t2= threading.Thread(target=run,args=("t2",)) 11 # t1.start() 12 # t2.start() 13 starttime=time.time() 14 t_obj=[] 15 print("-----------",threading.active_count(),threading.current_thread()) 16 for i in range(50): 17 t=threading.Thread(target=run,args=("t{}".format(i),)) 18 #t.setDaemon(True) 19 t.start() 20 t_obj.append(t) 21 print("-----------", threading.active_count(), threading.current_thread()) 22 23 for n in t_obj: 24 n.join() 25 26 time.sleep(3) 27 28 print(time.time()-starttime)
线程总数 51,包含主线程,50个子线程
----------- 1 <_MainThread(MainThread, started 3008)>
task t0
task t1
task t2
task t3
task t4
task t5
task t6
task t7
task t8
task t9
task t10
task t11
task t12
task t13
task t14
task t15
task t16
task t17
task t18
task t19
task t20
task t21
task t22
task t23
task t24
task t25
task t26
task t27
task t28
task t29
task t30
task t31
task t32
task t33
task t34
task t35
task t36
task t37
task t38
task t39
task t40
task t41
task t42
task t43
task t44
task t45
task t46
task t47
task t48
task t49
----------- 51 <_MainThread(MainThread, started 3008)>
5.036288022994995
Process finished with exit code 0
三、守护进程
只要主线程执行完毕,它不管子线程有没有执行完毕。就退出了。所以我现在就可以把所有的子线程变成所有的守护线程。变成守护线程之后,主程序就不会等子线程结束载退出了。它会等待非守护线程执行完毕才退出。所以不用管这些守护线程,守护线程是仆人,不重要,主线程不管的。
使用:setDaemon(True)
import threading import time def run(n): print("task",n) time.sleep(2) #代表处理某个功能代码需要2秒 # t1= threading.Thread(target=run,args=("t1",)) # t2= threading.Thread(target=run,args=("t2",)) # t1.start() # t2.start() starttime=time.time() t_obj=[] print("-----------",threading.active_count(),threading.current_thread()) for i in range(50): t=threading.Thread(target=run,args=("t{}".format(i),)) t.setDaemon(True) t.start() t_obj.append(t) print("-----------", threading.active_count(), threading.current_thread()) for n in t_obj: n.join() time.sleep(3) print(time.time()-starttime)
注意了:守护进程一定要在start之前设置,start之后就不能设置了,之后设置会报错,所以必须之前设置。从上面可以看出,主线程是执行完毕,但是不会等守护线程执行完毕。
3.2、使用场景
比如你写一个socket_server,每一个链接过来,socket_server就会给这个链接分配一个新的线程。如果我手动的把socket_server停掉。那这种情况你必须手动停掉服务,那它就要down了,这种情况下还要等线程结束吗?就不用等线程结束了,它自己就直接结束了。这样,是不是就可以把每个socket线程设置一个守护线程。主线程一旦down掉,就全部退出。

浙公网安备 33010602011771号