multiprocessing 充分利用cpu多核
一般情况下cpu密集使用进程池,IO密集使用线程池。python下想要充分利用多核CPU,就用多进程。

Process 类
Process 类用来描述一个进程对象。创建子进程的时候,只需要传入一个执行函数和函数的参数即可完成 Process 示例的创建。
star() 方法启动进程,
join() 方法实现进程间的同步,等待所有进程退出。
close() 用来阻止多余的进程涌入进程池 Pool 造成进程阻塞。

multiprocessing.Process(group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None)
group: 线程组,目前还没有实现,库引用中提示必须是None;
target 是函数名字,需要调用的函数
args 函数需要的参数,以 tuple 的形式传入

实例方法:
  is_alive():返回进程是否在运行。
  join([timeout]):阻塞当前上下文环境的进程程,直到调用此方法的进程终止或到达指定的timeout(可选参数)。
  start():进程准备就绪,等待CPU调度
  run():strat()调用run方法,如果实例进程时未制定传入target,这star执行t默认run()方法。
  terminate():不管任务是否完成,立即停止工作进程
属性:
  authkey
  daemon:和线程的setDeamon功能一样
  exitcode(进程在运行时为None、如果为–N,表示被信号N结束)
  name:进程名字。
  pid:进程号。

列子一:

import multiprocessing
import os def run_proc(name):
print('Child process {0} {1} Running '.format(name, os.getpid())) if __name__ == '__main__':
print('Parent process {0} is Running'.format(os.getpid()))
for i in range(5):
p = multiprocessing.Process(target=run_proc, args=(str(i),))
print('process start')
p.start()
p.join()
print('Process close')
[python@master test]$ python3 a.py
Parent process 12665 is Running
process start
process start
process start
Child process 0 12666 Running
process start
process start
Child process 2 12668 Running
Child process 1 12667 Running
Child process 3 12669 Running
Child process 4 12670 Running
Process close

列子二:

#coding=utf-8

import multiprocessing

def do(n) :
name = multiprocessing.current_process().name
print(name,'starting')
print ("worker ", n) if __name__ == '__main__' :
for i in range(5) :
p = multiprocessing.Process(target=do, args=(i,))
p.start()
p.join()
print ("Process end.")
[python@master test]$ python3 b.py
Process-1 starting
worker 0
Process end.
Process-2 starting
worker 1
Process end.
Process-3 starting
worker 2
Process end.
Process-4 starting
worker 3
Process end.
Process-5 starting
worker 4
Process end.

Pool类

进程池内部维护一个进程序列,当使用时,则去进程池中获取一个进程,如果进程池序列中没有可供使用的进进程,那么程序就会等待,直到进程池中有可用进程为止。进程池设置最好等于CPU核心数量
构造方法:

Pool([processes[, initializer[, initargs[, maxtasksperchild[, context]]]]])
processes :使用的工作进程的数量,如果processes是None那么使用 os.cpu_count()返回的数量。
initializer: 如果initializer是None,那么每一个工作进程在开始的时候会调用initializer(*initargs)。
maxtasksperchild:工作进程退出之前可以完成的任务数,完成后用一个新的工作进程来替代原进程,来让闲置的资源被释放。maxtasksperchild默认是None,意味着只要Pool存在工作进程就会一直存活。
context: 用在制定工作进程启动时的上下文,一般使用 multiprocessing.Pool() 或者一个context对象的Pool()方法来创建一个池,两种方法都适当的设置了context

实例方法:
  apply(func[, args[, kwds]]):同步进程池
  apply_async(func[, args[, kwds[, callback[, error_callback]]]]) :异步进程池
  close() : 关闭进程池,阻止更多的任务提交到pool,待任务完成后,工作进程会退出。
  terminate() : 结束工作进程,不在处理未完成的任务
  join() : wait工作线程的退出,在调用join()前,必须调用close() or terminate()。这样是因为被终止的进程需要被父进程调用wait(join等价与wait),否则进程会成为僵尸进程。

pool.join()必须使用在pool.close()或者pool.terminate()之后。其中close()跟terminate()的区别在于:
close()会等待池中的worker进程执行结束再关闭pool,而terminate()则是直接关闭。
异步进程池

#每次循环将会用空闲出来的子进程去调用目录--异步
#不等待只要进程池的位置空出来就立刻补上

# coding:utf-8
from multiprocessing import Pool
import time def Foo(i):
time.sleep(2)
return i + 100
def Bar(arg):
print("callback"+str(arg))
if __name__ == '__main__':
t_start=time.time()
pool = Pool(5)
for i in range(10):
pool.apply_async(func=Foo, args=(i,), callback=Bar)#维持执行的进程总数为processes,当一个进程执行完毕后会添加新的进程进去
pool.close()
pool.join() # 进程池中进程执行完毕后再关闭,如果注释,那么程序直接关闭。
pool.terminate()
t_end=time.time()
t=t_end-t_start
print ('the program time is :%s' %t)
[python@master test]$ python3 c.py
callback100
callback103
callback101
callback102
callback104
callback107
callback106
callback109
callback105
callback108
the program time is :4.0822553634643555

同步进程池

#阻塞式的请求 自加阻塞  顺序结构
#必须要在进程池中没有进程的的时候 才会有新进程进入进程池

# -*- coding:utf-8 -*-
from multiprocessing import Process, Pool
import time def Foo(i):
time.sleep(1)
print (i + 100)
if __name__ == '__main__':
t_start=time.time()
pool = Pool(5) #定义一个进程池,最大的进程数量
for i in range(10):
pool.apply(Foo, (i,))
pool.close()
pool.join() # 进程池中进程执行完毕后再关闭,如果注释,那么程序直接关闭。
t_end=time.time()
t=t_end-t_start
print('the program time is :%s' %t)
[python@master test]$ python3 d.py
100
101
102
103
104
105
106
107
108
109
the program time is :10.224181175231934

正确使用get()方法获取结果

# coding:utf-8
from multiprocessing import Pool
import time def Foo(i):
time.sleep(2)
return i + 100 def Bar(arg):
print('callback'+str(arg)) if __name__ == '__main__':
res_list=[]
t_start=time.time()
pool = Pool(5) for i in range(10):
res = pool.apply_async(func=Foo, args=(i,), callback=Bar)#维持执行的进程总数为processes,当一个进程执行完毕后会添加新的进程进去
res_list.append(res)
pool.close()
pool.join() # 进程池中进程执行完毕后再关闭,如果注释,那么程序直接关闭。
for res in res_list:
print(res.get())
pool.terminate()
t_end=time.time()
t=t_end-t_start
print ('the program time is :%s' %t)
[python@master test]$ python3 e.py
callback101
callback100
callback102
callback104
callback103
callback105
callback109
callback106
callback107
callback108
100
101
102
103
104
105
106
107
108
109
the program time is :4.145965099334717

进程数据共享

进程各自持有一份数据,默认无法共享数据

# coding:utf-8
from multiprocessing import Process
li = []
def foo(i):
li.append(i)
print ('say hi', li)
if __name__ == '__main__': for i in range(10):
p = Process(target=foo, args=(i,))
p.start() print ('ending', li)
[python@master test]$ python3 a.py
say hi []
say hi []
say hi []
say hi []
say hi []
say hi []
ending []
say hi []
say hi []
say hi []
say hi []

方法一(使用Array):

from multiprocessing import Process, Array

def f(a):
for i in range(len(a)):
a[i] = -a[i] if __name__ == '__main__':
arr = Array('i', range(10))
p = Process(target=f, args=(arr,))
p.start()
p.join() print(arr[:])
[python@master test]$ python3 b.py
[0, -1, -2, -3, -4, -5, -6, -7, -8, -9]

方法二(使用Manager):

Manager()返回的manager提供list, dict, Namespace, Lock, RLock, Semaphore, BoundedSemaphore, Condition, Event, Barrier, Queue, Value and Array类型的支持。

from multiprocessing import Process, Manager

def f(d, l):
d[] = ''
d['2'] = 2
d[0.25] = None
l.reverse() if __name__ == '__main__':
with Manager() as manager:
d = manager.dict()
l = manager.list(range(10)) p = Process(target=f, args=(d, l))
p.start()
p.join() print(d)
print(l)
[python@master test]$ python3 c.py
{1: '', '': 2, 0.25: None}
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

使用多个进程池:

#coding: utf-8
import multiprocessing
import os, time, random def Lee():
print ("\nRun task Lee-%s" %(os.getpid())) #os.getpid()获取当前的进程的ID
start = time.time()
time.sleep(random.random() * 10) #random.random()随机生成0-1之间的小数
end = time.time()
print ('Task Lee, runs %0.2f seconds.' %(end - start)) def Marlon():
print ("\nRun task Marlon-%s" %(os.getpid()))
start = time.time()
time.sleep(random.random() * 40)
end=time.time()
print ('Task Marlon runs %0.2f seconds.' %(end - start)) def Allen():
print ("\nRun task Allen-%s" %(os.getpid()))
start = time.time()
time.sleep(random.random() * 30)
end = time.time()
print ('Task Allen runs %0.2f seconds.' %(end - start)) def Frank():
print ("\nRun task Frank-%s" %(os.getpid()))
start = time.time()
time.sleep(random.random() * 20)
end = time.time()
print ('Task Frank runs %0.2f seconds.' %(end - start)) if __name__=='__main__':
function_list= [Lee, Marlon, Allen, Frank]
print ("parent process %s" %(os.getpid())) pool=multiprocessing.Pool(4)
for func in function_list:
pool.apply_async(func) #Pool执行函数,apply执行函数,当有一个进程执行完毕后,会添加一个新的进程到pool中 print ('Waiting for all subprocesses done...')
pool.close()
pool.join() #调用join之前,一定要先调用close() 函数,否则会出错, close()执行后不会有新的进程加入到pool,join函数等待素有子进程结束
print ('All subprocesses done.') [python@master test]$ python3 e.py
parent process 20714
Waiting for all subprocesses done... Run task Lee-20715 Run task Marlon-20716 Run task Allen-20718 Run task Frank-20717
Task Lee, runs 3.18 seconds.
Task Frank runs 11.47 seconds.
Task Allen runs 23.24 seconds.
Task Marlon runs 38.09 seconds.
All subprocesses done.

python之multiprocessing多进程的更多相关文章

  1. Python的Multiprocessing多进程实例

    最近在拜读RBG大神的faster-rcnn源码时发现他用了多进程去分阶段处理神经网络,原因如下: # ------------------------------------------------ ...

  2. python学习笔记——multiprocessing 多进程组件-队列Queue

    1 消息队列 1.1 基本语法 消息队列:multiprocessing.Queue,Queue是对进程安全的队列,可以使用Queue实现对进程之间的数据传输:还有一个重要作用是作为缓存使用. Que ...

  3. python学习笔记——multiprocessing 多进程组件 Pipe管道

    进程间通信(IPC InterProcess Communication)是值在不同进程间传播或交换信息. IPC通过有管道(无名管道 和 有名 / 命名管道).消息队列.共享存储 / 内容.信号量. ...

  4. python学习笔记——multiprocessing 多进程组件 进程池Pool

    1 进程池Pool基本概述 在使用Python进行系统管理时,特别是同时操作多个文件目录或者远程控制多台主机,并行操作可以节约大量时间,如果操作的对象数目不大时,还可以直接适用Process类动态生成 ...

  5. python学习笔记——multiprocessing 多进程模块Process

    系统自带的fork模块创建的多进程是基于Linux或Unix平台的,而window平台并不支持: python中的multiprocess为跨平台版本的多进程模块,支持子进程.通信和共享数据.执行不同 ...

  6. 关于python中的多进程模块multiprocessing

    python中的multiprocessing是一个多进程管理包,主要作用也就是提供多进程,而不是多线程,在其中用的比较多估计也就是Process和Pipe两个类,如下代码所示: #!/usr/bin ...

  7. python multiprocessing多进程应用

    multiprocessing包是Python中的多进程管理包,可以利用multiprocessing.Process对象来创建进程,Process对象拥有is_alive().join([timeo ...

  8. python笔记9 线程进程 threading多线程模块 GIL锁 multiprocessing多进程模块 同步锁Lock 队列queue IO模型

    线程与进程 进程 进程就是一个程序在一个数据集上的一次动态执行过程.进程一般由程序.数据集.进程控制块三部分组成.我们编写的程序用来描述进程要完成哪些功能以及如何完成:数据集则是程序在执行过程中所需要 ...

  9. Python中的多进程与多线程(一)

    一.背景 最近在Azkaban的测试工作中,需要在测试环境下模拟线上的调度场景进行稳定性测试.故而重操python旧业,通过python编写脚本来构造类似线上的调度场景.在脚本编写过程中,碰到这样一个 ...

随机推荐

  1. vue 登录页面填坑

    上边的导航头,会显示在登陆页面上,暂时的解决办法实: <template> <div style="position: fixed; top:0px; left:0px;h ...

  2. 搭建与破解wiki (confluence)

    搭建环境: 操作系统:contos7 数据库:5.5.60-MariaDB java版本: jdk-11.0.2 confluence版本:confluence6.7.1 一. 准备工作 下载conf ...

  3. Ironic 裸金属实例的部署流程

    目录 文章目录 目录 逻辑架构 部署架构 前提条件 部署流程 iSCSI Deploy UML PXE Deploy Driver Direct Deploy UML IPA Deploy Drive ...

  4. Spring Boot Application后台守护Daemon应用

    本地代码启动不报错,部署到服务器之后出现如下一个错误. 系统的日志如下: Error starting ApplicationContext. To display the conditions re ...

  5. Selenium下Chrome配置

    地址:https://peter.sh/experiments/chromium-command-line-switches/ chrome_options.add_argument('--headl ...

  6. React-Native传值方式之 :DeviceEventEmitter添加监听控制并传值到其他页面

    在 native 开发中,我们可以使用广播实现事件的订阅和事件的触发,从而实现不在该页面但是可以调用该页面的方法. 在 React Native 中,我们也可以使用 DeviceEventEmitte ...

  7. git 提交项目到远程仓库,简单实现忽略 node_modules文件

    在项目根目录中创建 .gitignore文件 在文件中添加你要忽略的文件 .DS_Store node_modules /dist # local env files .env.local .env. ...

  8. 安装 Git 并连接 Github

    下载安装 Git, 下载地址:https://git-scm.com/download/win . 在命令行中输入 git 测试 Git 是否安装成功. 在桌面鼠标右击打开 Git Bash Here ...

  9. PJzhang:网络数据单位小比特

    猫宁!!! 参考链接:https://blog.csdn.net/qq_38880380/article/details/79887704 https://www.cnblogs.com/Flycho ...

  10. Spring中重要的注解

    现在大部分的Spring项目都会用到注解.使用注解来替换xml,一行简单的注解就可以解决很多事情.但是你真的懂其中的原理吗. 本文翻译于 https://docs.spring.io/spring-f ...