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(“主线程”)这段代码结束,是整个的线程)
在守护线程、非守护子线程以及主线程(的代码)结束之后结束。
希望本篇文章能给你们带来帮助,觉得写的不错的可以给作者一些鼓励~您的支持就是我不断前行的动力!