多线程-守护线程
无论是进程还是线程,都遵循:守护进程/线程会等待主进程/线程运行完毕后被销毁
需要强调的是:运行完毕并非终止运行
1、对主进程来说,运行完毕指的是主进程代码运行完毕
2、对主线程来说,运行完毕指的是主线程所在的进程内所有非守护线程统统运行完毕,主线程才算运行完毕
详细解释:
1、主进程在其代码结束后就已经算运行完毕了(守护进程在此时就被回收),然后主进程会一直等非守护的子进程都运行完毕后回收子进程的资源(否则会产生僵尸进程),才会结束,
2、主线程在其他非守护线程运行完毕后才算运行完毕(守护线程在此时就被回收)。因为主线程的结束意味着进程的结束,进程整体的资源都将被回收,而进程必须保证非守护线程都运行完毕后才能结束。
验证:
from threading import Thread
import time
def sayhi(name):
time.sleep(2)
print('%s say hello' % name)
if __name__ == '__main__':
t = Thread(target=sayhi, args=('egon',))
t.setDaemon(True) # 必须在t.start()之前设置, t.daemon = True 也是一样的
t.start()
print('主线程')
print(t.is_alive())
输出:
主线程 True
解释:由于设置了t是守护线程,守护线程启动后就开始睡2秒,在睡的过程中,主线程完全可能执行完主线程的代码,打印出 “主线程”和“True”,主线程代码运行完后,守护线程就没有必要存在了,跟着陪葬,所以守护线程跟着死,那最终结果就不会打印 “egon say hello” 了。
思考下述代码的执行结果有可能是哪些情况?为什么?
from threading import Thread
import time
def foo():
print(123)
time.sleep(1)
print("end123")
def bar():
print(456)
time.sleep(3)
print("end456")
if __name__ == '__main__':
t1=Thread(target=foo)
t2=Thread(target=bar)
t1.daemon=True
t1.start()
t2.start()
print("main-------")
输出:
123 456 main------- end123 end456
解释:
程序启动3个线程t1,t2和主线程,首先启动t1并设置为守护线程,随即t1运行并打印123,然后睡1秒,睡1秒的过程中t2启动运行并打印456,然后睡3秒,由于启动线程很快,睡1秒的时间完全足以运行完t2最开始的打印456,以及在睡3秒过程中的主线程打印“main----------”,当主线程运行完成的时候,还需要等待非守护线程的运行,于是要继续等待t2的运行,由于t2是睡3秒,t1是睡1秒,所以t1先运行它睡1秒后的代码,打印“end123”,这时候t1守护线程代码运行完,主线程代码也运行完,但是程序不会结束,因为主线程还要等待非守护线程t2运行完毕才算完,t2睡3秒过后正常打印“end456”,随即整个程序运行完毕退出。
共有 0 条评论