49_并发编程-线程-守护进程
一、守护线程
1. 对主进程来说,运行完毕指的是主进程代码运行完毕
2. 对主线程来说,运行完毕指的是主线程所在的进程内所有非守护线程统统运行完毕,主线程才算运行完毕
详解:
<1>主进程在其代码结束后就已经算运行完毕了(守护进程在此时就被回收),然后主进程会一直等非守护的子进程都运行完毕后回收子进程的资源(否则会产生僵尸进程),才会结束
<2>主线程在其他非守护线程运行完毕后才算运行完毕(守护线程在此时就被回收)。因为主线程的结束意味着进程的结束,进程整体的资源都将被回收,而进程必须保证非守护线程都运行完毕后才能结束,因为进程执行结束是要回收资源的,所有必须确保你里面的非守护子线程全部执行完毕。
1 # 守护线程 - 主线程等待的是非守护进程结束 2 import time 3 from threading import Thread 4 from multiprocessing import Process 5 6 def func1(): 7 time.sleep(1) 8 print('func1') 9 10 def func2(): 11 time.sleep(2) 12 print('func2') 13 14 if __name__ == '__main__': 15 16 # 主线程会等待非守护线程结束后,主线程才结束,所以守护线程时间早就运行完毕会打印,主线程/func1/func2 17 t = Thread(target=func1) 18 t.daemon = True 19 t.start() 20 21 t = Thread(target=func2,) 22 t.start() 23 print('主进程') 24 25 # 主进程是等待给非守护进程收尸,主进程已结束,所以守护进程也会结束,打印主进程/func2; 相当于主进程的代码运行完,守护进程结束,而主进程没有死 26 t = Process(target=func1) 27 t.daemon = True # t.setDaemon(True) 也可,必须在t.start()之前设置 28 t.start() 29 30 t = Process(target=func2,) 31 t.start() 32 print('主进程')
二、信号量
信号量:控制同时能够进入锁内去执行代码的线程数量(进程数量),维护了一个计数器,刚开始创建信号量的时候假如设置的是4个房间,进入一次acquire就减1 ,出来一个就+1,如果计数器为0,那么其他的任务等待,这样其他的任务和正在执行的任务是一个同步的状态,而进入acquire里面去执行的那4个任务是异步执行的。