python使用多进程的实例详解


Posted in Python onSeptember 19, 2018

python多线程适合IO密集型场景,而在CPU密集型场景,并不能充分利用多核CPU,而协程本质基于线程,同样不能充分发挥多核的优势。

针对计算密集型场景需要使用多进程,python的multiprocessing与threading模块非常相似,支持用进程池的方式批量创建子进程。

•创建单个Process进程(使用func)

只需要实例化Process类,传递函数给target参数,这点和threading模块非常的类似,args为函数的参数

import os
from multiprocessing import Process
# 子进程要执行的代码
def task(name):
  print('run child process %s (%s)...' % (name, os.getpid()))
if __name__ == '__main__':
  print('parent process %s.' % os.getpid())
  p = Process(target=task, args=('test',))
  p.start()
  p.join()
  print('process end.')

•创建单个Process进程(使用class)

继承Process类,重写run方法创建进程,这点和threading模块基本一样

import multiprocessing
import os
from multiprocessing import current_process
class Worker(multiprocessing.Process):
  def run(self):
    name = current_process().name # 获取当前进程的名称
    print('run child process <%s> (%s)' % (name, os.getpid()))
    print('In %s' % self.name)
    return
if __name__ == '__main__':
  print('parent process %s.' % os.getpid())
  p = Worker()
  p.start()
  p.join()
  print('process end.') 
* 停止进程

terminate()结束子进程,但是会导致子进程的资源无法释放掉,是不推荐的做法,因为结束的时候不清楚子线程的运行状况,有很大可能性导致子线程在不恰当的时刻被结束。

import multiprocessing
import time
def worker():
  print('starting worker')
  time.sleep(0.1)
  print('finished worker')
if __name__ == '__main__':
  p = multiprocessing.Process(target=worker)
  print('执行前:', p.is_alive())
  p.start()
  print('执行中:', p.is_alive())
  p.terminate() # 发送停止号
  print('停止:', p.is_alive())
  p.join()
  print('等待完成:', p.is_alive())

•直接创建多个Process进程

import multiprocessing
def worker(num):
  print(f'Worker:%s %s', num)
  return
if __name__ == '__main__':
  jobs = []
  for i in range(5):
    p = multiprocessing.Process(target=worker, args=(i,))
    jobs.append(p)
    p.start()

•使用进程池创建多个进程

在利用Python进行系统管理的时候,特别是同时操作多个文件目录,或者远程控制多台主机,并行操作可以节约大量的时间。当被操作对象数目不大时,可以直接利用multiprocessing中的Process动态成生多个进程,十几个还好,但如果是上百个,上千个目标,手动的去限制进程数量却又太过繁琐,此时可以发挥进程池的功效。

Pool可以提供指定数量的进程供用户调用,当有新的请求提交到pool中时,如果池还没有满,那么就会创建一个新的进程用来执行该请求;但如果池中的进程数已经达到规定最大值,那么该请求就会等待,直到池中有进程结束,才会创建新的进程来它。

import os
import random
import time
from multiprocessing import Pool
from time import ctime
def task(name):
  print('start task %s (%s)...' % (name, os.getpid()))
  start = time.time()
  time.sleep(random.random() * 3)
  print('end task %s runs %0.2f seconds.' % (name, (time.time() - start)))
if __name__ == '__main__':
  print('parent process %s.' % os.getpid())
  p = Pool() # 初始化进程池
  for i in range(5):
    p.apply_async(task, args=(i,)) # 追加任务 apply_async 是异步非阻塞的,就是不用等待当前进程执行完毕,随时根据系统调度来进行进程切换。
  p.close()
  p.join() # 等待所有结果执行完毕,会等待所有子进程执行完毕,调用join()之前必须先调用close()
  print(f'all done at: {ctime()}')

如果关心每个进程的执行结果,可以使用返回结果的get方法获取,代码如下

import os
import random
import time
from multiprocessing import Pool, current_process
from time import ctime
def task(name):
  print('start task %s (%s)...' % (name, os.getpid()))
  start = time.time()
  time.sleep(random.random() * 3)
  print('end task %s runs %0.2f seconds.' % (name, (time.time() - start)))
  return current_process().name + 'done'
if __name__ == '__main__':
  print('parent process %s.' % os.getpid())
  result = []
  p = Pool() # 初始化进程池
  for i in range(5):
    result.append(p.apply_async(task, args=(i,))) # 追加任务 apply_async 是异步非阻塞的,就是不用等待当前进程执行完毕,随时根据系统调度来进行进程切换。
  p.close()
  p.join() # 等待所有结果执行完毕
  for res in result:
    print(res.get()) # get()函数得出每个返回结果的值
  print(f'all done at: {ctime()}')

总结

以上所述是小编给大家介绍的python使用多进程的实现代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Python 相关文章推荐
python读写ini文件示例(python读写文件)
Mar 25 Python
Python使用ftplib实现简易FTP客户端的方法
Jun 03 Python
浅谈python中的实例方法、类方法和静态方法
Feb 17 Python
Python爬取附近餐馆信息代码示例
Dec 09 Python
Python中elasticsearch插入和更新数据的实现方法
Apr 01 Python
Python在groupby分组后提取指定位置记录方法
Apr 20 Python
python操作excel文件并输出txt文件的实例
Jul 10 Python
Pycharm设置去除显示的波浪线方法
Oct 28 Python
python随机生成库faker库api实例详解
Nov 28 Python
python 统计文件中的字符串数目示例
Dec 24 Python
PyTorch在Windows环境搭建的方法步骤
May 12 Python
正确的理解和使用Django信号(Signals)
Apr 14 Python
Anaconda2 5.2.0安装使用图文教程
Sep 19 #Python
win10系统下Anaconda3安装配置方法图文教程
Sep 19 #Python
Window 64位下python3.6.2环境搭建图文教程
Sep 19 #Python
win10下python3.5.2和tensorflow安装环境搭建教程
Sep 19 #Python
win10下tensorflow和matplotlib安装教程
Sep 19 #Python
Python爬虫常用库的安装及其环境配置
Sep 19 #Python
Python开发虚拟环境使用virtualenvwrapper的搭建步骤教程图解
Sep 19 #Python
You might like
探讨:使用XMLSerialize 序列化与反序列化
2013/06/08 PHP
php使用qr生成二维码的示例分享
2014/01/20 PHP
php有道翻译api调用方法实例
2014/12/22 PHP
利用php输出不同的心形图案
2016/04/22 PHP
PHP编写简单的App接口
2016/08/28 PHP
PHP+redis实现的限制抢购防止商品超发功能详解
2019/09/19 PHP
Prototype 学习 Prototype对象
2009/07/12 Javascript
自己动手制作jquery插件之自动添加删除行的实现
2011/10/13 Javascript
js兼容的placeholder属性详解
2013/08/18 Javascript
Js base64 加密解密介绍
2013/10/11 Javascript
jquery高级编程的最佳实践详解
2014/03/23 Javascript
浅谈javascript面向对象程序设计
2015/01/21 Javascript
JavaScript焦点事件、鼠标事件和滚轮事件使用详解
2016/01/15 Javascript
javascript中不易分清的slice,splice和split三个函数
2016/03/29 Javascript
全面解析标签页的切换方式
2016/08/21 Javascript
一步一步封装自己的HtmlHelper组件BootstrapHelper(二)
2016/09/14 Javascript
老生常谈的跨域处理
2017/01/11 Javascript
微信小程序获取循环元素id以及wx.login登录操作
2017/08/17 Javascript
React.Js添加与删除onScroll事件的方法详解
2017/11/03 Javascript
taro开发微信小程序的实践
2019/05/21 Javascript
[47:31]完美世界DOTA2联赛PWL S3 INK ICE vs DLG 第一场 12.12
2020/12/16 DOTA
用Python制作简单的钢琴程序的教程
2015/04/01 Python
python+pyqt实现右下角弹出框
2017/10/26 Python
Python selenium爬取微博数据代码实例
2020/05/22 Python
基于logstash实现日志文件同步elasticsearch
2020/08/06 Python
python利用tkinter实现图片格式转换的示例
2020/09/28 Python
来自圣地亚哥的实惠太阳镜:Knockaround
2018/08/27 全球购物
波兰在线香水店:Perfumy.pl
2019/08/12 全球购物
英文自荐信格式
2013/11/28 职场文书
关于是否需要写商业计划书
2014/02/07 职场文书
幼儿园中班教师个人总结
2015/02/05 职场文书
电影地道战观后感
2015/06/04 职场文书
2015年学校管理工作总结
2015/07/20 职场文书
互联网创业商业模式以及赚钱法则有哪些?
2019/10/12 职场文书
详解TypeScript中的类型保护
2021/04/29 Javascript
解析CSS 提取图片主题色功能(小技巧)
2021/05/12 HTML / CSS