python多程序之守護程序
不懂愛恨情仇煎熬的我們,總以為殉情隻是古老的傳言。
1.僅有一個程序存在,且該程序為守護子程序:
此時子程序守護着主程序,隻要主程序結束,子程序就跟着結束
from multiprocessing import Process
import time
def task(name):
print(f"{name} is running")
time.sleep(2)
print(f"{name} is gone")
if __name__ == "__main__":
p = Process(target=task,args=("常辛",)) # 建立一個程序對象
p.start()
p.daemon = True # 一定要在子程序開啟之前設定
print("主程序")
這裡設定在了子程序開始之前,是以執行結果報錯:
assert self._popen is None, 'process has already started'
AssertionError: process has already started
常辛 is running
常辛 is gone
我們将p.daemon = True放到p.start之前再來看看:
from multiprocessing import Process
import time
def task(name):
print(f"{name} is running")
time.sleep(2)
print(f"{name} is gone")
if __name__ == "__main__":
p = Process(target=task,args=("常辛",)) # 建立一個程序對象
p.daemon = True # 将p子程序設定成守護程序,隻要主程序結束,守護程序馬上結束
p.start()
print("主程序")
主程序
我們可以看到執行完主程序就沒有執行子程序了(哪怕就一句,因為時間上來不及)
我們延緩下主程序的結束時間看看:
from multiprocessing import Process
import time
def task(name):
print(f"{name} is running")
time.sleep(2)
print(f"{name} is gone")
if __name__ == "__main__":
p = Process(target=task,args=("常辛",)) # 建立一個程序對象
p.daemon = True # 将p子程序設定成守護程序,隻要主程序結束,守護程序馬上結束
p.start()
time.sleep(1)
print("主程序")
常辛 is running
主程序
則程式成功執行了子程序的第一句代碼。
2.程序中不僅有守護程序存在,還有非守護程序:
from multiprocessing import Process
import time
def task():
print(123)
time.sleep(1)
print(f"end123")
def task1():
print(456)
time.sleep(3)
print(f"end456")
def task2():
print(789)
time.sleep(5)
print(f"end789")
if __name__ == "__main__":
p1 = Process(target=task) # 建立一個程序對象
p2 = Process(target=task1) # 建立一個程序對象
p3 = Process(target=task2) # 建立一個程序對象
p2.daemon = True # 将p2子程序設定成守護程序,隻要主程序結束,守護程序馬上結束
p1.start()
p2.start()
p3.start()
# time.sleep(1)
print("主程序")
主程序
123
789
end123
end789
我們可以看到執行完主程序後沒有執行子程序p2,(上邊說過時間來不及),但是為什麼p1和p3照樣執行?
原因如下:由于p1,p3都是子程序,需要開辟記憶體空間,需要耗費時間,是以會優先輸出主程序,由于p2是守護子程序,p1和p3是非守護子程序,當主程序執行完畢(注意主程序還沒有退出,因為還有p1和p3非守護程序),p2守護程序也就沒了,但是還有p1和p3非守護程序,是以p1和p3會執行自己的代碼任務,當p1和p3執行完畢,那麼主程序也就退出了,進而整個程式就退出了。
我們延緩下主程序的結束時間再繼續看看:
from multiprocessing import Process
import time
def task():
print(123)
time.sleep(1)
print(f"end123")
def task1():
print(456)
time.sleep(3)
print(f"end456")
def task2():
print(789)
time.sleep(5)
print(f"end789")
if __name__ == "__main__":
p1 = Process(target=task) # 建立一個程序對象
p2 = Process(target=task1) # 建立一個程序對象
p3 = Process(target=task2) # 建立一個程序對象
p2.daemon = True # 将p2子程序設定成守護程序,隻要主程序結束,守護程序馬上結束
p1.start()
p2.start()
p3.start()
time.sleep(1)
print("主程序")
123
456
789
主程序
end123
end789
程式成功執行了子程序p2的第一句代碼,然後主程序的代碼結束後,p2也随之結束,等待p1和p3這兩個非守護子程序結束後,該程序才算完整結束。
python多線程之守護程序
多線程的守護程序寫法和多程序一樣,都是放到start之前。
因為線程開啟速度非常非常快(比主線程還快,這裡先舉例給大家看:)
from threading import Thread
def sayhi(name):
print(111)
print("%s say hello" % name)
if __name__ == "__main__":
t = Thread(target=sayhi,args=("egon",))
t.start() # 線程的開啟速度比程序的要快很多
print("主線程")
111
egon say hello
主線程
我們可以看到先執行完線程的内容,再執行的主線程。
言歸正傳,守護線程也是讓子線程,在主線程結束時候結束,下邊給大家進行講解。
1.僅有一個線程存在,且該線程為守護子線程:
from threading import Thread
import time
def sayhi(name):
print(111)
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("主線程")
111
主線程
我們可以看到,當主線程結束時候,因為子線程還在等待sleep,是以時間上夠主線程執行,然後主程序執行完畢——程式結束,子線程也終止了。
這裡注意:t.setDaemon(True)和t.daemon = True都為守護線程的寫法(二者皆可)
2.線程中不僅有守護線程存在,還有非守護線程:
from threading import Thread
import time
def foo():
print(123)
time.sleep(2)
print("end123")
def foo1():
print(456)
time.sleep(1)
print("end456")
def foo2():
print(789)
time.sleep(1)
print("end789")
if __name__ == "__main__":
t1 = Thread(target=foo)
t2 = Thread(target=foo1)
t3 = Thread(target=foo2)
t1.daemon = True
t1.start()
t2.start()
t3.start()
# time.sleep(3)
print("主線程")
123
456
789
主線程
end456
end789
從結果中,我們可以看出,在執行了程式後,t1、t2、t3三個子線程先執行了第一句print,然後在等待sleep時,執行了主線程。因為t1是守護程序,随着主線程代碼的結束,t1子線程随之結束,而t2和t3是非守護線程,雖然這裡以及執行完了主線程這段代碼,但是對主線程來說,運作完畢指的是主線程所在的程序内所有非守護線程統統運作完畢,主線程才算運作完畢,是以會執行t2、t3的sleep後的代碼。
總結:主線程什麼時候結束?(不是 print(“主線程”)這段代碼結束,是整個的線程)
在守護線程、非守護子線程以及主線程(的代碼)結束之後結束。
希望本篇文章能給你們帶來幫助,覺得寫的不錯的可以給作者一些鼓勵~您的支援就是我不斷前行的動力!