python进程池停止_python进程池详解

1,Python的multiprocessing 实现多cpu 多进程

为啥用multiprocessing?

*现在cpu都多核了, 写大型程序你还在用单线程的传统写法?很不fashion而且效率很低, 你out了。

*那用multi-threading不就结了?C语言可以, 编译完执行没问题。 但是python这种解释型的语言用多线程就不行了, python的multithreading效率并不高。据说是受制于GIL (global interpreter lock) 的锁机制, 该锁只能工作于单个cpu core。这样别的cpu core干着急也帮不上忙。

*那怎么办呢? 自己fork一堆子进程,然后管理呗? 呵呵,DIY?这不是重新造轮子吗。

*亲, 用python现成的multiprocessing库吧。支持多个cpu core,简直就是为了多核cpu打造的, python 2.6之后都支持。

不用说了,直接上干货

*sample 1, 创建process, target=f 函数名, args传递参数

# encoding: utf8

# @Time : 2017/10/26 20:54

# @Author : Ycs

# @Site :

# @File : mymultiprocessing.py

# @Desc : Python的multiprocessing 实现多cpu 多进程, python进程池multiprocessing.Pool和线程池multiprocessing.dummy.Pool实例

from multiprocessing import Process,Queue,Pipe,Pool

import time

def f(name):

print('hello:', name)

if __name__ == '__main__':

#创建process, target=f 函数名, args传递参数

p=Process(target=f,args=('bbb',))

p.start()

p.join()

#支持队列

def ff(q):

q.put([42,None,'hello'])

if __name__ == '__main__':

q=Queue()

p=Process(target=ff,args=(q,))

p.start()

print(q.get()) #这里prints "[42, None, 'hello']"

p.join()

#支持Pipe

def f3(conn):

conn.send([43,None,'hello'])

conn.close()

if __name__ == '__main__':

parent_conn,child_conn=Pipe()

p=Process(target=f3,args=(child_conn,))

p.start()

print(parent_conn.recv()) # 这里prints "[42, None, 'hello']"

p.join()

#支持Pool, 雇一群worker来干活

def f4(x):

return x*x

if __name__ == '__main__':

pool=Pool(processes=4) # start 4 worker processes

result=pool.apply_async(f4,(10,)) # evaluate "f(10)" asynchronously

try:

print(result.get(timeout=1))

except TimeoutError:

pass

print(pool.map(f4,range(10)))

it=pool.imap(f4,range(10))

print(it.next())

print(it.next())

print(it.next(timeout=1)) # raises TimeoutError

result=pool.apply_async(time.sleep,(10,))

print(result.get(timeout=1))

注意事项:

* 在UNIX平台上,当某个进程终结之后,该进程需要被其父进程调用wait,否则进程成为僵尸进程(Zombie)。所以,有必要对每个Process对象调用join()方法 (实际上等同于wait)。对于多线程来说,由于只有一个进程,所以不存在此必要性。

* multiprocessing提供了threading包中没有的IPC(比如Pipe和Queue),效率上更高。应优先考虑Pipe和Queue,避免使用Lock/Event/Semaphore/Condition等同步方式 (因为它们占据的不是用户进程的资源)。

* 多进程应该避免共享资源。在多线程中,我们可以比较容易地共享资源,比如使用全局变量或者传递参数。在多进程情况下,由于每个进程有自己独立的内存空间,以上方法并不合适。此时我们可以通过共享内存和Manager的方法来共享资源。但这样做提高了程序的复杂度,并因为同步的需要而降低了程序的效率。

Reference:

[1] http://www.ibm.com/developerworks/aix/library/au-multiprocessing

[2] http://docs.python.org/2/library/multiprocessing.html

python中的多进程处理

1)Process

要创建一个Process是很简单的。

from multiprocessing import Process

def f(name):

print('hello', name)

if __name__ == '__main__':

p = Process(target=f, args=('bob',))

p.start()

p.join()

要获得一个Process的进程ID也是很简单的。

from multiprocessing import Process

import os

def info(title):

print title

print 'module name:', __name__

print 'process id:', os.getpid()

def f(name):

info('function f')

print 'hello', name

if __name__ == '__main__':

info('main line')

p = Process(target=f, args=('bob',))

p.start()

p.join()

创建进程:multiprocessing.Process([group[, target[, name[, args[, kargs]]]]])

参数:

group:    None,它的存在仅仅是为了与threading.Thread兼容

target:   一般是函数

name:     进程名

args:     函数的参数

kargs:    keywords参数

函数:

run()                  默认的run()函数调用target的函数,你也可以在子类中覆盖该函数

start()                启动该进程

join([timeout])        父进程被停止,直到子进程被执行完毕。

当timeout为None时没有超时,否则有超时。

进程可以被join很多次,但不能join自己

is_alive()

terminate()            结束进程。

在Unix上使用的是SIGTERM

在Windows平台上使用TerminateProcess

属性:

name                   进程名

daemon                 守护进程

pid                    进程ID

exitcode               如果进程还没有结束,该值为None

authkey

2)Queue

Queue类似于queue.Queue,一般用来进程间交互信息

例子:

from multiprocessing import Process, Queue

def f(q):

q.put([42, None, 'hello'])

if __name__ == '__main__':

q = Queue()

p = Process(target=f, args=(q,))

p.start()

print(q.get())    # prints "[42, None, 'hello']"

p.join()

注意:Queue是进程和线程安全的。

Queue实现了queue.Queue的大部分方法,但task_done()和join()没有实现。

创建Queue:multiprocessing.Queue([maxsize])

函数:

qsize()                             返回Queue的大小

empty()                             返回一个boolean值表示Queue是否为空

full()                              返回一个boolean值表示Queue是否满

put(item[, block[, timeout]])

put_nowait(item)

get([block[, timeout]])

get_nowait()

get_no_wait()

close()                             表示该Queue不在加入新的元素

join_thread()

cancel_join_thread()

3)JoinableQueue

创建:multiprocessing.JoinableQueue([maxsize])

task_done()

join()

4)Pipe

from multiprocessing import Process, Pipe

def f(conn):

conn.send([42, None, 'hello'])

conn.close()

if __name__ == '__main__':

parent_conn, child_conn = Pipe()

p = Process(target=f, args=(child_conn,))

p.start()

print(parent_conn.recv())   # prints "[42, None, 'hello']"

p.join()

multiprocessing.Pipe([duplex])      返回一个Connection对象

5)异步化synchronization

from multiprocessing import Process, Lock

def f(l, i):

l.acquire()

print('hello world', i)

l.release()

if __name__ == '__main__':

lock = Lock()

for num in range(10):

Process(target=f, args=(lock, num)).start()

6)Shared Memory

from multiprocessing import Process, Value, Array

def f(n, a):

n.value = 3.1415927

for i in range(len(a)):

a[i] = -a[i]

if __name__ == '__main__':

num = Value('d', 0.0)

arr = Array('i', range(10))

p = Process(target=f, args=(num, arr))

p.start()

p.join()

print(num.value)

print(arr[:])

1>Value

2>Array

7)Manager

from multiprocessing import Process, Manager

def f(d, l):

d[1] = '1'

d['2'] = 2

d[0.25] = None

l.reverse()

if __name__ == '__main__':

manager = Manager()

d = manager.dict()

l = manager.list(range(10))

p = Process(target=f, args=(d, l))

p.start()

p.join()

print(d)

print(l)

8)Pool

from multiprocessing import Pool

def f(x):

return x*x

if __name__ == '__main__':

pool = Pool(processes=4)              # start 4 worker processes

result = pool.apply_async(f, [10])     # evaluate "f(10)" asynchronously

print result.get(timeout=1)           # prints "100" unless your computer is *very* slow

print pool.map(f, range(10))          # prints "[0, 1, 4,..., 81]"

multiprocessing.Pool([processes[, initializer[, initargs]]])

函数:

apply(func[, args[, kwds]])

apply_async(func[, args[, kwds[, callback]]])

map(func,iterable[, chunksize])

map_async(func,iterable[, chunksize[, callback]])

imap(func, iterable[, chunksize])

imap_unordered(func, iterable[, chunksize])

close()

terminate()

join()

from multiprocessing import Pool

def f(x):

return x*x

if __name__ == '__main__':

pool = Pool(processes=4)              # start 4 worker processes

result = pool.apply_async(f, (10,))   # evaluate "f(10)" asynchronously

print(result.get(timeout=1))          # prints "100" unless your computer is *very* slow

print(pool.map(f, range(10)))         # prints "[0, 1, 4,..., 81]"

it = pool.imap(f, range(10))

print(next(it))                       # prints "0"

print(next(it))                       # prints "1"

print(it.next(timeout=1))             # prints "4" unless your computer is *very* slow

import time

result = pool.apply_async(time.sleep, (10,))

print(result.get(timeout=1))          # raises TimeoutError

9)杂项

multiprocessing.active_children()          返回所有活动子进程的列表

multiprocessing.cpu_count()                返回CPU数目

multiprocessing.current_process()          返回当前进程对应的Process对象

multiprocessing.freeze_support()

multiprocessing.set_executable()

10)Connection对象

send(obj)

recv()

fileno()

close()

poll([timeout])

send_bytes(buffer[, offset[, size]])

recv_bytes([maxlength])

recv_bytes_info(buffer[, offset])

>>> from multiprocessing import Pipe

>>> a, b = Pipe()

>>> a.send([1, 'hello', None])

>>> b.recv()

[1, 'hello', None]

>>> b.send_bytes('thank you')

>>> a.recv_bytes()

'thank you'

>>> import array

>>> arr1 = array.array('i', range(5))

>>> arr2 = array.array('i', [0] * 10)

>>> a.send_bytes(arr1)

>>> count = b.recv_bytes_into(arr2)

>>> assert count == len(arr1) * arr1.itemsize

>>> arr2

array('i', [0, 1, 2, 3, 4, 0, 0, 0, 0, 0])

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值