通过实例解析python创建进程常用方法


Posted in Python onJune 19, 2020

 运行程序时,单线程或单进程往往是比较慢的,为加快程序运行速度,我们可以使用多进程,可以理解为多任务同时运行,小编的电脑是四核,所以可以设置四个进程。

下面,我们来了解下多进程的使用:

1、使用multiprocessing模块创建进程

multiprocessing模块提供了一个Process类来代表进程对象,语法如下:

Process([group[,target[,name[,args[,kwargs]]]]])

其中,group:参数未使用,值始终是None

target:表示当前进程启动时执行的可调用对象

name:为当前进程实例的别名

args:表示传递给target函数的参数元组

kwargs:表示传递给target函数的参数字典

使用多进程的一个简单例子:

from multiprocessing import Process   # 导入模块

# 执行子进程代码
def test(interval):
  print('我是子进程')
# 执行主程序
def main():
  print('主进程开始')
  # 实例化Procss进程类
  p = Process(target=test,args=(1,))
  # 启动子进程
  p.start()
  print('主进程结束')

if __name__ == '__main__':
  main()

结果:

主进程开始
主进程结束
我是子进程

Process的实例p常用的方法除start()外,还有如下常用方法:

is_alive():判断进程实例是否还在执行

join([timeout]):是否等待进程实例执行结束,或等待多少秒

start():启动进程实例(创建子进程)

run():如果没有给定target参数,对这个对象调用start()方法时,就将执行对象中的run()方法

terminate():不管任务是否完成,立即终止

Process类还有如下常用属性:

name:当前进程实例别名,默认为Process-N,N为从1开始递增的整数

pid:当前进程实例的PID值

下面是Process类方法和属性的使用,创建两个子进程,分别使用os模块和time模块输出父进程和子进程的id以及子进程的时间,并调用Process类的name和pid属性:

# -*- coding:utf-8 -*-
from multiprocessing import Process
import time
import os

#两个子进程将会调用的两个方法
def child_1(interval):
  print("子进程(%s)开始执行,父进程为(%s)" % (os.getpid(), os.getppid()))
  # 计时开始
  t_start = time.time()
  # 程序将会被挂起interval秒
  time.sleep(interval)
  # 计时结束
  t_end = time.time()
  print("子进程(%s)执行时间为'%0.2f'秒"%(os.getpid(),t_end - t_start))

def child_2(interval):
  print("子进程(%s)开始执行,父进程为(%s)" % (os.getpid(), os.getppid()))
  # 计时开始
  t_start = time.time()
  # 程序将会被挂起interval秒
  time.sleep(interval)
  # 计时结束
  t_end = time.time()
  print("子进程(%s)执行时间为'%0.2f'秒"%(os.getpid(),t_end - t_start))

if __name__ == '__main__':
  print("------父进程开始执行-------")
  # 输出当前程序的ID
  print("父进程PID:%s" % os.getpid())
  # 实例化进程p1
  p1=Process(target=child_1,args=(1,))
  # 实例化进程p2
  p2=Process(target=child_2,name="mrsoft",args=(2,))
  # 启动进程p1
  p1.start()
  # 启动进程p2
  p2.start()
  #同时父进程仍然往下执行,如果p2进程还在执行,将会返回True
  print("p1.is_alive=%s"%p1.is_alive())
  print("p2.is_alive=%s"%p2.is_alive())
  #输出p1和p2进程的别名和PID
  print("p1.name=%s"%p1.name)
  print("p1.pid=%s"%p1.pid)
  print("p2.name=%s"%p2.name)
  print("p2.pid=%s"%p2.pid)
  print("------等待子进程-------")
  # 等待p1进程结束
  p1.join()
  # 等待p2进程结束
  p2.join()
  print("------父进程执行结束-------")

结果:

------父进程开始执行-------
父进程PID:13808
p1.is_alive=True
p2.is_alive=True
p1.name=Process-1
p1.pid=13360
p2.name=mrsoft
p2.pid=21500
------等待子进程-------
子进程(13360)开始执行,父进程为(13808)
子进程(21500)开始执行,父进程为(13808)
子进程(13360)执行时间为'1.01'秒
子进程(21500)执行时间为'2.00'秒
------父进程执行结束-------

上述代码中,第一次实例化Process类时,会为name属性默认赋值为Process-1,第二次则默认为Process-2,但由于实例化进程p2时,设置了name属性为mrsoft,所以p2.name的值为mrsoft。

2、使用Process子类创建进程

对于一些简单的小任务,通常使用Process(target=test)方式实现多进程。但如果要处理复杂任务的进程,通常定义一个类,使其继承Process类,下面是通过使用Process子类创建多个进程。

# -*- coding:utf-8 -*-
from multiprocessing import Process
import time
import os

#继承Process类
class SubProcess(Process):
  # 由于Process类本身也有__init__初识化方法,这个子类相当于重写了父类的这个方法
  def __init__(self,interval,name=''):
    # 调用Process父类的初始化方法
    Process.__init__(self)
    # 接收参数interval
    self.interval = interval
    # 判断传递的参数name是否存在
    if name:
      # 如果传递参数name,则为子进程创建name属性,否则使用默认属性
      self.name = name    
  #重写了Process类的run()方法
  def run(self):
    print("子进程(%s) 开始执行,父进程为(%s)"%(os.getpid(),os.getppid()))
    t_start = time.time()
    time.sleep(self.interval)
    t_stop = time.time()
    print("子进程(%s)执行结束,耗时%0.2f秒"%(os.getpid(),t_stop-t_start))

if __name__=="__main__":
  print("------父进程开始执行-------")
  # 输出当前程序的ID
  print("父进程PID:%s" % os.getpid())         
  p1 = SubProcess(interval=1,name='mrsoft')
  p2 = SubProcess(interval=2)
  #对一个不包含target属性的Process类执行start()方法,就会运行这个类中的run()方法,
  #所以这里会执行p1.run()
  # 启动进程p1
  p1.start()
  # 启动进程p2
  p2.start() 
  # 输出p1和p2进程的执行状态,如果真正进行,返回True,否则返回False
  print("p1.is_alive=%s"%p1.is_alive())
  print("p2.is_alive=%s"%p2.is_alive())
  #输出p1和p2进程的别名和PID
  print("p1.name=%s"%p1.name)
  print("p1.pid=%s"%p1.pid)
  print("p2.name=%s"%p2.name)
  print("p2.pid=%s"%p2.pid)
  print("------等待子进程-------")
  # 等待p1进程结束
  p1.join()
  # 等待p2进程结束
  p2.join() 
  print("------父进程执行结束-------")

结果:

------父进程开始执行-------
父进程PID:2512
p1.is_alive=True
p2.is_alive=True
p1.name=mrsoft
p1.pid=20328
p2.name=SubProcess-2
p2.pid=13700
------等待子进程-------
子进程(20328) 开始执行,父进程为(2512)
子进程(13700) 开始执行,父进程为(2512)
子进程(20328)执行结束,耗时1.00秒
子进程(13700)执行结束,耗时2.00秒
------父进程执行结束-------

上述代码中,定义了一个SubProcess子类,继承multiprocess.Process父类。SubProcess子类中定义了两个方法:__init__()初始化方法和run()方法,在__init__()初始化方法中,调用父类multiprocess.Process的__init__()初始化方法,否则父类的__init__()方法会被覆盖,无法开启进程。此外,在SubProcess子类中没有定义start()方法,但在主程序中却调用了start()方法,此时就会自动执行SubProcess类的run()方法。

3、使用进程池Pool创建进程

上面我们使用Process类创建了两个进程,但如果要创建十几个或者上百个进程,则需要实例化更多的Process类,解决这一问题的方法就是使用multiprocessing模块提供的pool类,即Pool进程池。

我们先来了解下Pool类的常用方法:

apply_async(func[,args[,kwds]]):使用非阻塞方式调用func()函数(并行执行,阻塞方式必须等待上一个进程退出才能执行下一个进程),args为传递给func()函数的参数列表, kwds为传递给func()函数的关键字参数列表

apply(func[,args[,kwds]]):使用阻塞方式调用func()函数

close():关闭Pool,使其不再接受新的任务

terminate():不管任务是否完成,立即终止

join():主进程阻塞,等待子进程的退出,必须在close或terminate之后使用

下面通过一个示例演示一下如何通过进程池创建多进程,设置最大进程数为3,使用非阻塞方式执行10个任务:

# -*- coding=utf-8 -*-
from multiprocessing import Pool
import os, time

def task(name):
  print('子进程(%s)执行task %s ...' % ( os.getpid() ,name))
  # 休眠1秒
  time.sleep(1)    

if __name__=='__main__':
  print('父进程(%s).' % os.getpid())
  # 定义一个进程池,最大进程数3
  p = Pool(3)    
  # 从0开始循环10次  
  for i in range(10):
    # 使用非阻塞方式调用task()函数 
    p.apply_async(task, args=(i,))  
  print('等待所有子进程结束...')
  # 关闭进程池,关闭后p不再接收新的请求
  p.close()
  # 等待子进程结束
  p.join()  
  print('所有子进程结束.')

结果:

父进程(3856).
等待所有子进程结束...
子进程(18872)执行task 0 ...
子进程(11220)执行task 1 ...
子进程(10140)执行task 2 ...
子进程(18872)执行task 3 ...
子进程(11220)执行task 4 ...
子进程(10140)执行task 5 ...
子进程(18872)执行task 6 ...
子进程(11220)执行task 7 ...
子进程(10140)执行task 8 ...
子进程(18872)执行task 9 ...
所有子进程结束.

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

Python 相关文章推荐
从零学Python之入门(五)缩进和选择
May 27 Python
Python中的exec、eval使用实例
Sep 23 Python
Python列出一个文件夹及其子目录的所有文件
Jun 30 Python
python目录与文件名操作例子
Aug 28 Python
详解Python中最难理解的点-装饰器
Apr 03 Python
python爬取拉勾网职位数据的方法
Jan 24 Python
python实现超市扫码仪计费
May 30 Python
Django 中使用流响应处理视频的方法
Jul 20 Python
Python获取二维数组的行列数的2种方法
Feb 11 Python
在Windows上安装和配置 Jupyter Lab 作为桌面级应用程序教程
Apr 22 Python
python opencv pytesseract 验证码识别的实现
Aug 28 Python
python中Array和DataFrame相互转换的实例讲解
Feb 03 Python
keras model.fit 解决validation_spilt=num 的问题
Jun 19 #Python
为什么是 Python -m
Jun 19 #Python
Python 私有属性和私有方法应用场景分析
Jun 19 #Python
Python基于network模块制作电影人物关系图
Jun 19 #Python
keras中的History对象用法
Jun 19 #Python
python中rc1什么意思
Jun 19 #Python
解决keras backend 越跑越慢问题
Jun 18 #Python
You might like
PHP实现根据设备类型自动跳转相应页面的方法
2014/07/24 PHP
PHP读MYSQL中文乱码的快速解决方法
2016/10/01 PHP
PHP实现微信提现功能(微信商城)
2019/11/21 PHP
javascript &&和||运算法的另类使用技巧
2009/11/28 Javascript
jquery异步调用页面后台方法‏(asp.net)
2011/03/01 Javascript
jQuery实现id模糊查询的小例子
2013/03/19 Javascript
JS、CSS加载中的小问题探讨
2013/11/26 Javascript
jquery中event对象属性与方法小结
2013/12/18 Javascript
JS文本获得焦点清除文本文字的示例代码
2014/01/13 Javascript
js使用循环清空某个div中的input标签值
2014/09/29 Javascript
深入理解JS中的Function.prototype.bind()方法
2016/10/11 Javascript
Javascript中字符串replace方法的第二个参数探究
2016/12/05 Javascript
ES5 ES6中Array对象去除重复项的方法总结
2017/04/27 Javascript
Ionic + Angular.js实现图片轮播的方法示例
2017/05/21 Javascript
原生JS实现DOM加载完成马上执行JS代码的方法
2018/09/07 Javascript
VueJS 组件参数名命名与组件属性转化问题
2018/12/03 Javascript
如何手动实现es5中的bind方法详解
2018/12/07 Javascript
JavaScript设计模式之观察者模式实例详解
2019/01/16 Javascript
微信小程序实现轨迹回放的示例代码
2019/12/13 Javascript
菜鸟使用python实现正则检测密码合法性
2016/01/05 Python
Python实现选择排序
2017/06/04 Python
Python 加密与解密小结
2018/12/06 Python
python设定并获取socket超时时间的方法
2019/01/12 Python
Python numpy中矩阵的基本用法汇总
2019/02/12 Python
iPython pylab模式启动方式
2020/04/24 Python
selenium+python自动化78-autoit参数化与批量上传功能的实现
2021/03/04 Python
html svg生成环形进度条的实现方法
2019/09/23 HTML / CSS
Belle Maison倍美丛官网:日本千趣会旗下邮购网站
2016/07/22 全球购物
日本土著品牌,综合型购物网站:Cecile
2016/08/23 全球购物
澳大利亚最好的厨具店:Kitchen Warehouse
2018/03/13 全球购物
继承时候类的执行顺序问题,一般都是选择题,问你将会打印出什么?
2015/11/18 面试题
关于环保的标语
2014/06/13 职场文书
文员试用期转正自我鉴定
2014/09/14 职场文书
2014年销售人员工作总结
2014/11/27 职场文书
女性健康知识讲座主持词
2015/07/04 职场文书
员工规章制度范本
2015/08/07 职场文书