python多进程关闭_python之multiprocessing多进程

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 process12665 isRunning

process start

process start

process start

Child process0 12666Running

process start

process start

Child process2 12668Running

Child process1 12667Running

Child process3 12669Running

Child process4 12670Running

Processclose

列子二:

#coding=utf-8import multiprocessing

def do(n) :

name=multiprocessing.current_process().nameprint(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-1starting

worker0Processend.

Process-2starting

worker1Processend.

Process-3starting

worker2Processend.

Process-4starting

worker3Processend.

Process-5starting

worker4Processend.

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

frommultiprocessing import Pool

import time

def Foo(i):

time.sleep(2)return i + 100def 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_startprint ('the program time is :%s' %t)[python@master test]$ python3 c.py

callback100

callback103

callback101

callback102

callback104

callback107

callback106

callback109

callback105

callback108

the program timeis :4.0822553634643555

同步进程池

#阻塞式的请求 自加阻塞  顺序结构

#必须要在进程池中没有进程的的时候 才会有新进程进入进程池

# -*- coding:utf-8 -*-

frommultiprocessing 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_startprint('the program time is :%s' %t)[python@master test]$ python3 d.py100

101

102

103

104

105

106

107

108

109the program timeis :10.224181175231934

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

# coding:utf-8

frommultiprocessing import Pool

import time

def Foo(i):

time.sleep(2)return i + 100def 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 inres_list:print(res.get())

pool.terminate()

t_end=time.time()

t=t_end-t_startprint ('the program time is :%s' %t)[python@master test]$ python3 e.py

callback101

callback100

callback102

callback104

callback103

callback105

callback109

callback106

callback107

callback108100

101

102

103

104

105

106

107

108

109the program timeis :4.145965099334717

进程数据共享

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

# coding:utf-8

frommultiprocessing 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[0]say hi[2]say hi[3]say hi[5]say hi[1]say hi[6]ending[]say hi[7]say hi[4]say hi[9]say hi[8]

方法一(使用Array):

frommultiprocessing 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类型的支持。

frommultiprocessing import Process, Manager

def f(d, l):

d[1] = '1'd['2'] = 2d[0.25] =None

l.reverse()if __name__ == '__main__':with Manager() asmanager:

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: '1', '2': 2, 0.25: None}[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

使用多个进程池:

#coding: utf-8import 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 infunction_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 process20714Waitingfor allsubprocesses done...

Run task Lee-20715Run task Marlon-20716Run task Allen-20718Run task Frank-20717Task Lee, runs3.18seconds.

Task Frank runs11.47seconds.

Task Allen runs23.24seconds.

Task Marlon runs38.09seconds.All subprocesses done.

你可能感兴趣的:(python多进程关闭)