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实现封装得到virustotal扫描结果
Oct 05 Python
在Python的框架中为MySQL实现restful接口的教程
Apr 08 Python
详解Django中的ifequal和ifnotequal标签使用
Jul 16 Python
Python将图片转换为字符画的方法
Jun 16 Python
从运行效率与开发效率比较Python和C++
Dec 14 Python
解决Pycharm调用Turtle时 窗口一闪而过的问题
Feb 16 Python
Django框架 查询Extra功能实现解析
Sep 04 Python
修改 CentOS 6.x 上默认Python的方法
Sep 06 Python
python GUI库图形界面开发之PyQt5信号与槽的高级使用技巧装饰器信号与槽详细使用方法与实例
Mar 06 Python
PyQt5如何将.ui文件转换为.py文件的实例代码
May 26 Python
python程序实现BTC(比特币)挖矿的完整代码
Jan 20 Python
浅析python连接数据库的重要事项
Feb 22 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
php empty() 检查一个变量是否为空
2011/11/10 PHP
解决PHP程序运行时:Fatal error: Maximum execution time of 30 seconds exceeded in的错误提示
2016/11/25 PHP
浅析PHP echo 和 print 语句
2020/06/30 PHP
javascript 写类方式之五
2009/07/05 Javascript
Javascript 判断函数类型完美解决方案
2009/09/02 Javascript
图片轮换效果实现代码(点击按钮停止执行)
2013/04/12 Javascript
JS将表单导出成EXCEL的实例代码
2013/11/11 Javascript
js模仿hover的具体实现代码
2013/12/30 Javascript
javascript计时器事件使用详解
2014/01/07 Javascript
Jquery获得控件值的三种方法总结
2014/02/13 Javascript
jquery插件开发之实现jquery手风琴功能分享
2014/03/10 Javascript
jQuery学习笔记之 Ajax操作篇(一) - 数据加载
2014/06/23 Javascript
使用cluster 将自己的Node服务器扩展为多线程服务器
2014/11/10 Javascript
js使用Array.prototype.sort()对数组对象排序的方法
2015/01/28 Javascript
JS+CSS实现带关闭按钮DIV弹出窗口的方法
2015/02/27 Javascript
javascript实现删除前弹出确认框
2015/06/04 Javascript
javascript中tostring()和valueof()的用法及两者的区别
2015/11/16 Javascript
jQuery中$.each()函数的用法引申实例
2016/05/12 Javascript
详解AngularJs中$sce与$sceDelegate上下文转义服务
2016/09/21 Javascript
深入理解 JavaScript 中的 JSON
2017/04/06 Javascript
vue2.0 实现导航守卫(路由守卫)
2018/05/21 Javascript
vue-video-player 通过自定义按钮组件实现全屏切换效果【推荐】
2018/08/29 Javascript
2款Python内存检测工具介绍和使用方法
2014/06/01 Python
Python学习教程之常用的内置函数大全
2017/07/14 Python
python构建基础的爬虫教学
2018/12/23 Python
Python 3.8新特征之asyncio REPL
2019/05/28 Python
Python爬虫之Selenium警告框(弹窗)处理
2020/12/04 Python
一个基于canvas的移动端图片编辑器的实现
2020/10/28 HTML / CSS
什么是三层交换,说说和路由的区别在那里
2014/09/01 面试题
医学护理系毕业生求职信
2013/10/01 职场文书
通信工程毕业生自荐信
2013/11/01 职场文书
聚美优品广告词改编
2014/03/14 职场文书
机关干部四风问题自查报告及整改措施
2014/10/26 职场文书
音乐课《小猫钓鱼》教学反思
2016/02/18 职场文书
品德与社会教学反思
2016/02/24 职场文书
Nginx四层负载均衡的配置指南
2021/06/11 Servers