python实现守护进程、守护线程、守护非守护并行

作者:Saflyer 时间:2021-02-03 09:06:56 

守护进程

1、守护子进程

主进程创建守护进程

  1. 其一:守护进程会在主进程代码执行结束后就终止

  2. 其二:守护进程内无法再开启子进程,否则抛出异常:AssertionError: daemonic processes are not allowed to havechildren

注意:进程之间是互相独立的,主进程代码运行结束,守护进程随即终止

我们来看一个例子


from multiprocessing import Process
import os,time,random

def task():
 print('%s is running' %os.getpid())
 time.sleep(2)
 print('%s is done' %os.getpid())

#守护进程内无法再开启子进程,否则抛出异常
 # p = Process(target=time.sleep, args=(3,))
 # p.start()

if __name__ == '__main__':
 p=Process(target=task)
 p.daemon = True #1、必须在p.start()之前
 p.start()
 print('主')

输出结果如下:

原因是:主进程程序启动执行到p子进程,由于子进程需要开辟内存空间,由于需要耗费时间,所以主进程会首先输出“主”,由于主进程执行完毕,那么守护子进程p也就 * 掉了,随之主进程也就退出了

如果上面代码修改如下,加上 p.join()这一行代码


if __name__ == '__main__':
 p=Process(target=task)
 p.daemon = True #1、必须在p.start()之前
 p.start()
 p.join()
 print('主')

那么程序会输出如下:

14732 is running

14732 is done

join以前也分析过,是起到阻塞作用,子进程执行完毕,才执行主进程,所以加上join

1、执行到join,是起到阻塞作用,就会执行子进程,然后执行完毕,在执行主进程

2、也可以这样理解,执行到join,由于主进程print(“主”)没有执行完,所以守护进程不会 * 掉,继续执行

1、守护子进程、非守护子进程并存

在上面的例子是子进程只有一个守护进程,在主进程执行完毕,守护子进程就会 * 掉 ,我们在来看一个,子进程既有守护子进程,又包含非守护子进程


from multiprocessing import Process
from threading import Thread
import time,os
def foo():
 print(123)
 time.sleep(1)
 print("end123")

def bar():

print(456)
 time.sleep(3)
 print("end456")

if __name__ == '__main__':
 p1=Process(target=foo)
 p2 = Process(target=bar)
 p1.daemon=True
 p1.start()
 p2.start()
 print("main-------")

输出如下:

main-------
456
end456

原因如下:由于p1,p2都是子进程,需要开辟内存空间,需要耗费时间,所以会优先输出主进程“main”,由于p1是守护子进程,p2是非守护子进程,当主进程执行完毕(注意之类主进程还没有退出,因为还有p2非守护进程),p1守护进程也就退了,但是还有一个p2非守护进程,所以p2会执行自己的代码任务,当p2执行完毕,那么主进程也就退出了,进而整个程序就退出了

守护线程

守护子线程

无论是进程还是线程,都遵循:守护xxx会等待主xxx运行完毕后被销毁

需要强调的是:运行完毕并非终止运行

1.对主进程来说,运行完毕指的是主进程代码运行完毕

2.对主线程来说,运行完毕指的是主线程所在的进程内所有非守护线程统统运行完毕,主线程才算运行完毕

详细解释:

1 主进程在其代码结束后就已经算运行完毕了(守护进程在此时就被回收),然后主进程会一直等非守护的子进程都运行完毕后回收子进程的资源(否则会产生僵尸进程),才会结束,

2 主线程在其他非守护线程运行完毕后才算运行完毕(守护线程在此时就被回收)。因为主线程的结束意味着进程的结束,进程整体的资源都将被回收,而进程必须保证非守护线程都运行完毕后才能结束。

我们先来看一个例子


from multiprocessing import Process
from threading import Thread
import os,time,random
def task():
 # t=Thread(target=time.sleep,args=(3,))
 # t.start()
 print('%s is running' %os.getpid())
 time.sleep(2)
 print('%s is done' %os.getpid())

if __name__ == '__main__':
 t=Thread(target=task)
 t.daemon = True
 t.start()
 print('主')

 输出如下:

13368 is running

原因是:

在执行到守护子线程t,由于主线程子线程通用一块内存,所以不存在不同进程创建各自空间,所以就先输出子进程的执行任务代码,所以输出print(‘%s is running' %os.getpid()),由于time.sleep(2),所以就会执行主线程“main”,然后主线程执行完毕,那么即使2秒过后,由于主线程执行完毕,那么子守护线程也就退出了,所以 print(‘%s is done' %os.getpid())就不会执行了

守护子线程非守护子进程并存

我们解析来看一个守护子线程非守护子进程并存的例子


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

t2.start()
 t1.start()
 print("main-------")

输出如下:

456
123
main-------

end123

end456

原因是:

t1是守护子线程,t2非守护子线程,跟主线程使用一块内存,所以会输出t1,t1子线程的任务代码,所以执行456,123由于t1,t2都有睡眠时间,所以执行主线程代码,然后对主线程来说,运行完毕指的是主线程所在的进程内所有非守护线程统统运行完毕,主线程才算运行完毕,所以会执行t1,t2睡眠后的任务代码,然后程序退出。

我们会问为什么t1守护子线程,也会执行sleep后的代码,不是说主线程代码执行完毕,守护线程就 * 掉了吗?这里要注意是对主线程来说,运行完毕指的是主线程所在的进程内所有非守护线程统统运行完毕,主线程才算运行完毕,当时t2还没执行完毕

来源:https://blog.csdn.net/u013210620/article/details/78710532

标签:python,守护进程,守护线程
0
投稿

猜你喜欢

  • python tkiner实现 一个小小的图片翻页功能的示例代码

    2023-07-19 18:40:32
  • 论Asp与XML的关系

    2008-03-05 12:01:00
  • MySQL高级特性之集合函数

    2009-02-26 16:19:00
  • python下载图片实现方法(超简单)

    2021-12-21 02:17:07
  • Golang Gin局部和全局中间件使用详解

    2023-07-10 03:03:00
  • python模拟登录百度贴吧(百度贴吧登录)实例

    2023-11-20 14:30:56
  • jQuery点击改变链接的文本

    2010-03-19 18:11:00
  • python自制包并用pip免提交到pypi仅安装到本机【推荐】

    2023-12-14 19:33:23
  • Asp.net实现简单的文字水印

    2007-08-24 09:28:00
  • python继承threading.Thread实现有返回值的子类实例

    2023-06-07 19:01:15
  • Python常见数据结构之栈与队列用法示例

    2023-11-03 20:58:10
  • Python中assert函数的使用(含源代码)

    2022-07-18 19:46:49
  • C#调用Python模块的方法

    2021-04-13 15:29:10
  • Python中常见的导入方式总结

    2023-03-04 18:22:03
  • 全面解读Python Web开发框架Django

    2022-06-24 19:41:45
  • 建立MySQL数据库日常维护规范

    2009-03-20 12:34:00
  • Mootools 1.2教程(16)——排序类和方法简介

    2008-12-10 14:18:00
  • python Gunicorn服务器使用方法详解

    2021-09-06 00:35:08
  • 解析:MySQL 数据库搜索中大小写敏感性

    2009-02-23 17:32:00
  • python求质数的3种方法

    2023-02-12 04:07:54
  • asp之家 网络编程 m.aspxhome.com