Python多进程编程常用方法解析


Posted in Python onMarch 26, 2020

python中的多线程其实并不是真正的多线程,如果想要充分地使用多核CPU资源,在python中大部分情况需要使用多进程。python提供了非常好用的多进程包Multiprocessing,只需要定义一个函数,python会完成其它所有事情。借助这个包,可以轻松完成从单进程到并发执行的转换。multiprocessing支持子进程、通信和共享数据、执行不同形式的同步,提供了Process、Queue、Pipe、LocK等组件

一、Process

语法:Process([group[,target[,name[,args[,kwargs]]]]])

参数含义:target表示调用对象;args表示调用对象的位置参数元祖;kwargs表示调用对象的字典。name为别名,groups实际上不会调用。

方法:is_alive():

 join(timeout):

 run():

 start():

 terminate():

属性:authkey、daemon(要通过start()设置)、exitcode(进程在运行时为None、如果为-N,表示被信号N结束)、name、pid。其中daemon是父进程终止后自动终止,且自己不能产生新的进程,必须在start()之前设置。

1.创建函数,并将其作为单个进程

from multiprocessing import Process
def func(name):
 print("%s曾经是好人"%name)
if __name__ == "__main__":
 p = Process(target=func,args=('kebi',))
 p.start() #start()通知系统开启这个进程

2.创建函数并将其作为多个进程

from multiprocessing import Process
import random,time

def hobby_motion(name):
 print('%s喜欢运动'% name)
 time.sleep(random.randint(1,3))

def hobby_game(name):
 print('%s喜欢游戏'% name)
 time.sleep(random.randint(1,3))

if __name__ == "__main__":
 p1 = Process(target=hobby_motion,args=('付婷婷',))
 p2 = Process(target=hobby_game,args=('科比',))
 p1.start()
 p2.start()

执行结果:

付婷婷喜欢运动
科比喜欢游戏

3.将进程定义为类(开启进程的另一种方法,并不是很常用)

from multiprocessing import Process
class MyProcess(Process):
 def __init__(self,name):
 super().__init__()
 self.name = name
 def run(self): #start()时,run自动调用,而且此处只能定义为run。
 print("%s曾经是好人"%self.name)
if __name__ == "__main__":
 p = MyProcess('kebi')
 p.start() #将Process当作父类,并且自定义一个函数。

4.daemon程序对比效果

不加daemon属性

import time
def func(name):
 print("work start:%s"% time.ctime())
 time.sleep(2)
 print("work end:%s"% time.ctime())

if __name__ == "__main__":
 p = Process(target=func,args=('kebi',))
 p.start()
 print("this is over")
#执行结果
this is over
work start:Thu Nov 30 16:12:00 2017
work end:Thu Nov 30 16:12:02 2017

加上daemon属性

from multiprocessing import Process
import time
def func(name):
 print("work start:%s"% time.ctime())
 time.sleep(2)
 print("work end:%s"% time.ctime())

if __name__ == "__main__":
 p = Process(target=func,args=('kebi',))
 p.daemon = True #父进程终止后自动终止,不能产生新进程,必须在start()之前设置
 p.start()
 print("this is over")

#执行结果
this is over

设置了daemon属性又想执行完的方法:

import time
def func(name):
 print("work start:%s"% time.ctime())
 time.sleep(2)
 print("work end:%s"% time.ctime())

if __name__ == "__main__":
 p = Process(target=func,args=('kebi',))
 p.daemon = True
 p.start()
 p.join() #执行完前面的代码再执行后面的
 print("this is over")

#执行结果
work start:Thu Nov 30 16:18:39 2017
work end:Thu Nov 30 16:18:41 2017
this is over

5.join():上面的代码执行完毕之后,才会执行后i面的代码。

先看一个例子:

from multiprocessing import Process
import time,os,random
def func(name,hour):
 print("A lifelong friend:%s,%s"% (name,os.getpid()))
 time.sleep(hour)
 print("Good bother:%s"%name)
if __name__ == "__main__":
 p = Process(target=func,args=('kebi',2))
 p1 = Process(target=func,args=('maoxian',1))
 p2 = Process(target=func,args=('xiaoniao',3))
 p.start()
 p1.start()
 p2.start()
 print("this is over")

执行结果:

this is over #最后执行,最先打印,说明start()只是开启进程,并不是说一定要执行完
A lifelong friend:kebi,12048
A lifelong friend:maoxian,8252
A lifelong friend:xiaoniao,6068
Good bother:maoxian #最先打印,第二位执行
Good bother:kebi
Good bother:xiaoniao

添加join()

from multiprocessing import Process
import time,os,random
def func(name,hour):
 print("A lifelong friend:%s,%s"% (name,os.getpid()))
 time.sleep(hour)
 print("Good bother:%s"%name)
start = time.time()
if __name__ == "__main__":
 p = Process(target=func,args=('kebi',2))
 p1 = Process(target=func,args=('maoxian',1))
 p2 = Process(target=func,args=('xiaoniao',3))
 p.start()
 p.join() #上面的代码执行完毕之后,再执行后面的
 p1.start()
 p1.join()
 p2.start()
 p2.join()
 print("this is over")
 print(time.time() - start)
#执行结果
A lifelong friend:kebi,14804
Good bother:kebi
A lifelong friend:maoxian,11120
Good bother:maoxian
A lifelong friend:xiaoniao,10252 #每个进程执行完了,才会执行下一个
Good bother:xiaoniao
this is over
6.497815370559692 #2+1+3+主程序执行时间

改变一下位置

from multiprocessing import Process
import time,os,random
def func(name,hour):
 print("A lifelong friend:%s,%s"% (name,os.getpid()))
 time.sleep(hour)
 print("Good bother:%s"%name)
start = time.time()
if __name__ == "__main__":
 p = Process(target=func,args=('kebi',2))
 p1 = Process(target=func,args=('maoxian',1))
 p2 = Process(target=func,args=('xiaoniao',3))
 p.start()
 p1.start()
 p2.start()
 p.join() #需要2秒
 p1.join() #到这时已经执行完
 p2.join() #已经执行了2秒,还要1秒
 print("this is over")
 print(time.time() - start)
#执行结果
A lifelong friend:kebi,13520
A lifelong friend:maoxian,11612
A lifelong friend:xiaoniao,17064 #几乎是同时开启执行
Good bother:maoxian
Good bother:kebi
Good bother:xiaoniao
this is over
3.273620367050171 #以最长时间的为主

6.其它属性和方法

from multiprocessing import Process
import time
def func(name):
 print("work start:%s"% time.ctime())
 time.sleep(2)
 print("work end:%s"% time.ctime())

if __name__ == "__main__":
 p = Process(target=func,args=('kebi',))
 p.start()
 p.terminate() #将进程杀死,而且必须放在start()后面,与daemon的功能类似

#执行结果
this is over
from multiprocessing import Process
import time
def func(name):
 print("work start:%s"% time.ctime())
 time.sleep(2)
 print("work end:%s"% time.ctime())

if __name__ == "__main__":
 p = Process(target=func,args=('kebi',))
 # p.daemon = True
 print(p.is_alive())
 p.start()
 print(p.name) #获取进程的名字
 print(p.pid) #获取进程的pid
 print(p.is_alive()) #判断进程是否存在
 print("this is over")

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

Python 相关文章推荐
python的类变量和成员变量用法实例教程
Aug 25 Python
Python爬取京东的商品分类与链接
Aug 26 Python
Python变量和数据类型详解
Feb 15 Python
Python 基础教程之包和类的用法
Feb 23 Python
python 中字典嵌套列表的方法
Jul 03 Python
python scp 批量同步文件的实现方法
Jan 03 Python
Python unittest单元测试框架及断言方法
Apr 15 Python
基于python实现地址和经纬度转换
May 19 Python
Python绘制组合图的示例
Sep 18 Python
详解Anaconda安装tensorflow报错问题解决方法
Nov 01 Python
python Xpath语法的使用
Nov 26 Python
一篇文章带你搞懂Python类的相关知识
May 20 Python
简单了解python调用其他脚本方法实例
Mar 26 #Python
Python tornado上传文件的功能
Mar 26 #Python
Python Tornado批量上传图片并显示功能
Mar 26 #Python
python列表删除和多重循环退出原理详解
Mar 26 #Python
执行Python程序时模块报错问题
Mar 26 #Python
python3 正则表达式基础廖雪峰
Mar 25 #Python
python 6.7 编写printTable()函数表格打印(完整代码)
Mar 25 #Python
You might like
mysql,mysqli,PDO的各自不同介绍
2012/09/19 PHP
如何利用PHP执行.SQL文件
2013/07/05 PHP
PHP实现把MySQL数据库导出为.sql文件实例(仿PHPMyadmin导出功能)
2014/05/10 PHP
PHP获取毫秒级时间戳的方法
2015/04/15 PHP
WordPress中邮件的一些修改和自定义技巧
2015/12/15 PHP
CI框架无限级分类+递归的实现代码
2016/11/01 PHP
在 Laravel 6 中缓存数据库查询结果的方法
2019/12/11 PHP
PHP 判断字符串是中文还是英文, 或者是中英混合
2021/03/09 PHP
Jquery动态添加输入框的方法
2015/05/29 Javascript
javascript实现设置、获取和删除Cookie的方法
2015/06/01 Javascript
js格式化时间的方法
2015/12/18 Javascript
javascript中类的定义方式详解(四种方式)
2015/12/22 Javascript
微信小程序 Record API详解及实例代码
2016/09/30 Javascript
深入理解Javascript箭头函数中的this
2017/02/13 Javascript
Angularjs 双向绑定时字符串的转换成数字类型的问题
2017/06/12 Javascript
使用js获取伪元素的content实例
2017/10/24 Javascript
Vue.js在数组中插入重复数据的实现代码
2017/11/17 Javascript
微信小程序代码上传、审核发布小程序
2019/05/18 Javascript
小程序实现多个选项卡切换
2020/06/19 Javascript
[01:23:24]DOTA2-DPC中国联赛 正赛 PSG.LGD vs Elephant BO3 第三场 2月7日
2021/03/11 DOTA
python实现的多线程端口扫描功能示例
2017/01/21 Python
python爬虫_微信公众号推送信息爬取的实例
2017/10/23 Python
python分批定量读取文件内容,输出到不同文件中的方法
2018/12/08 Python
NumPy 基本切片和索引的具体使用方法
2019/04/24 Python
用python求一个数组的和与平均值的实现方法
2019/06/29 Python
python通过实例讲解反射机制
2019/10/17 Python
Python数据可视化:箱线图多种库画法
2019/11/06 Python
python图形开发GUI库pyqt5的详细使用方法及各控件的属性与方法
2020/02/14 Python
法国发饰品牌:Alexandre De Paris
2018/12/04 全球购物
为什么要用EJB
2014/04/17 面试题
三个Unix的命令面试题
2015/04/12 面试题
探矿工程师自荐信
2014/01/24 职场文书
大学生毕业求职自荐书范文
2014/02/04 职场文书
技校学生个人职业生涯规划范文
2014/03/03 职场文书
85句关于理想的名言警句大全
2019/08/22 职场文书
一文了解MYSQL三大范式和表约束
2022/04/03 MySQL