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. SDK location not found. Define location with sdk.dir in the local.properties file or with an ANDROID_HOME environment variable.

    问题描述: 已经安装了android-sdk 和gradle环境,并配置了环境变量,如下所示: android环境 root@wangju-HP--G4:/home/wangju/Desktop/5i ...

  2. Sql UpdateOrInsert

    SqlServer(先更新,受影响条数为0,则Insert,通过事务): begin tran update table set column=columnvalue where wherestr b ...

  3. C++的学习笔记1

    一:      为了惯例具有指针成员的类,必须定义三个复制控制成员:复制构造函数.赋值操作符和析构函数.  复制构造函数分配新元素并从被复制对象处复制值,赋值操作符撤销所保存的原对象并从右操作数向左操 ...

  4. flask 学习(二)

    安装了flask扩展 以及flask-bootstrap 默认情况下,flask在template文件夹寻找模板. flask 加载的是Jinja2模板,该模板引擎在flask中由函数render_t ...

  5. yum安装epel源

    国内yum源的安装(163,阿里云,epel)   国内yum源的安装(163,阿里云,epel) ----阿里云镜像源 1.备份 mv /etc/yum.repos.d/CentOS-Base.re ...

  6. JS进阶学习<一>

    一:区分大小写: 1. JS是区分大小写的,如:classname和ClassName是不一样的.同时注意方法.属性.变量等的大小写吆. 2. JS中的字符.符号等一定要在英文状态下输入吆. 二:变量 ...

  7. python在shell中环境变量使用

    1.用Python Shell设置或获取环境变量的方法: 设置系统环境变量 os.environ['环境变量名称']='环境变量值' #其中key和value均为string类型 os.putenv( ...

  8. CommonJS、AMD、CMD、ES6——JavaScript模块化

    CommonJS规范:Node AMD规范:RequireJS CMD规范:SeaJS ES6模块

  9. Leetcode之广度优先搜索(BFS)专题-127. 单词接龙(Word Ladder)

    Leetcode之广度优先搜索(BFS)专题-127. 单词接龙(Word Ladder) BFS入门详解:Leetcode之广度优先搜索(BFS)专题-429. N叉树的层序遍历(N-ary Tre ...

  10. leveldb Arena源码分析

    前言 对于一个高性能的服务器程序来说,内存的使用非常重要.C++提供new/delete来管理内存的申请和释放,但是对于小对象来说,直接使用new/delete代价比较大,要付出额外的空间和时间,性价 ...