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


Posted in Python onMay 05, 2018

守护进程

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还没执行完毕

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python通过colorama模块在控制台输出彩色文字的方法
Mar 19 Python
浅谈Python数据类型之间的转换
Jun 08 Python
使用Python读写及压缩和解压缩文件的示例
Jul 08 Python
Python 私有函数的实例详解
Sep 11 Python
python实现识别手写数字 python图像识别算法
Mar 23 Python
Anaconda下安装mysql-python的包实例
Jun 11 Python
Django添加feeds功能的示例
Aug 07 Python
python pandas库的安装和创建
Jan 10 Python
详解python做UI界面的方法
Feb 27 Python
详解PyCharm+QTDesigner+PyUIC使用教程
Jun 13 Python
python读取与处理netcdf数据方式
Feb 14 Python
Python hashlib模块的使用示例
Oct 09 Python
Linux(Redhat)安装python3.6虚拟环境(推荐)
May 05 #Python
Python3中的json模块使用详解
May 05 #Python
Python 编码规范(Google Python Style Guide)
May 05 #Python
python 编码规范整理
May 05 #Python
PYTHON基础-时间日期处理小结
May 05 #Python
python 日期操作类代码
May 05 #Python
Python批量发送post请求的实现代码
May 05 #Python
You might like
ThinkPHP的I方法使用详解
2014/06/18 PHP
Laravel框架实现的使用smtp发送邮件功能示例
2019/03/12 PHP
select组合框option的捕捉实例代码
2008/09/30 Javascript
让div层随鼠标移动的实现代码 ie ff
2009/12/18 Javascript
js 事件处理函数间的Event物件是否全等
2011/04/08 Javascript
jQuery 图片切换插件(代码比较少)
2012/05/07 Javascript
你必须知道的JavaScript 中字符串连接的性能的一些问题
2013/05/07 Javascript
jquery实现公告翻滚效果
2015/02/27 Javascript
js实现完全自定义可带多级目录的网页鼠标右键菜单方法
2015/02/28 Javascript
jQuery操作表单常用控件方法小结
2015/03/23 Javascript
浅谈jQuery this和$(this)的区别及获取$(this)子元素对象的方法
2016/11/29 Javascript
利用jQuery插件imgAreaSelect实现图片上传裁剪(同步显示图像位置信息)
2016/12/02 Javascript
JS常见算法详解
2017/02/28 Javascript
js中编码函数:escape,encodeURI与encodeURIComponent详解
2017/03/21 Javascript
微信小程序教程系列之设置标题栏和导航栏(7)
2020/06/29 Javascript
JS利用prototype给类添加方法操作详解
2019/06/21 Javascript
Vue实现剪贴板复制功能
2019/12/31 Javascript
微信小程序 wx:for 与 wx:for-items 与 wx:key的正确用法
2020/05/19 Javascript
Vuex的热更替如何实现
2020/06/05 Javascript
vue3为什么要用proxy替代defineProperty
2020/10/19 Javascript
Python 实现简单的shell sed替换功能(实例讲解)
2017/09/29 Python
JavaScript实现一维数组转化为二维数组
2018/04/17 Python
详解程序意外中断自动重启shell脚本(以Python为例)
2019/07/26 Python
对Python 中矩阵或者数组相减的法则详解
2019/08/26 Python
Python上下文管理器类和上下文管理器装饰器contextmanager用法实例分析
2019/11/07 Python
解决pyshp UnicodeDecodeError的问题
2019/12/06 Python
使用 Python 读取电子表格中的数据实例详解
2020/04/17 Python
Canvas制作的下雨动画的示例
2018/03/06 HTML / CSS
John Hardy官方网站:手工设计首饰的奢侈品牌
2017/07/05 全球购物
介绍一下Java中的Class类
2015/04/10 面试题
小学生作文评语大全
2014/04/21 职场文书
地球物理学专业推荐信
2014/09/08 职场文书
2014年残联工作总结
2014/11/21 职场文书
党支部考察鉴定意见
2015/06/02 职场文书
Python selenium模拟网页点击爬虫交管12123违章数据
2021/05/26 Python
Java并发编程之Executor接口的使用
2021/06/21 Java/Android