Python之进程(multiprocessing)

一、multiprocessing模块简介——进程基于“threading”的接口

multiprocessing模块支持创建进程——使用threading模块相似的API。multiprocessing模块对本地和远程的并发都提供了支持,使用子进程(subprocesses)来替代threads解决了GIL的限制。因此,multiprocessing模块允许程序充分利用给定设备的多核资源。在Unix和Windows系统都可以运行。

 multiprocessing模块同样引入了threading模块不支持的APIs。主要例子如:Pool对象提供了便捷并行执行(有多输入)的函数的执行,通过进程分发输入数据。下面就是一个简单的数据分发。

from multiprocessing import Pool

def f(x):
    return x*x

if __name__ == '__main__':
    p = Pool(5)
    print(p.map(f, [1, 2, 3]))
样例

二、Process类

在multiprocessing模块中,processes可以通过创建一个Process对象产生。然后调用其start()方法。Process和threading.Thread遵循threading.Thread的API。一个简单的多线程例子如下

from multiprocessing import Process

def f(name):
    print 'hello', name

if __name__ == '__main__':
    p = Process(target=f, args=('bob',))
    p.start()
    p.join()
样例

显示相应的单个进程IDs,如下:

from multiprocessing import Process
import os
import time


def info(title):
    print(title)
    print('module name:', __name__)
    if hasattr(os, 'getppid'):
        print('parent process:',os.getppid())
    print('process id:', os.getpid())


def f(name):
    time.sleep(2)
    info('function f')
    print('hello', name)

if __name__ == '__main__':

    info('main line')
    p = Process(target=f,args=('bob',))
    p.start()
    p.join()
样例

 三、Exchanging objects between processes进程间通讯

1、Queue基本上是Queue.Queue的克隆版,但是本Queue是线程和进程都安全的

from multiprocessing import Process, Queue
import time


def f(q):
    time.sleep(2)
    q.put([42, None, 'hello'])
    print('f')

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    p.join()
    print('hello')
    print(q.get())
样例

2、Pipes是Pipe()函数返回一个连接对象对——由一个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())
    p.join()
样例

Pipe()返回两个连接(Connection)对象,代表管道的两端。每个连接对象都有send()和recv()方法(彼此之间)。

注意:如果两个线程(或进程)同时尝试从pipe的同一端读写数据,管道里的数据可能损坏。如果同时在pipe()的两端读写是没有风险的。

四、进程间的同步机制

multiprocessing拥有threading模块相同的同步机制。例如,可以使用lock来保证一次只有一个进程打印到标准输出。

from multiprocessing import Process,Lock
import time


def f(l, i):
    l.acquire()
    # time.sleep(2)
    print('hello world', i)
    l.release()

if __name__ == '__main__':
    lock = Lock()

    for num in range(10):
        Process(target=f,args=(lock, num)).start()
利用锁线程同步

五、进程间共享状态

如上所述,我们在做并发编程时,应当尽可能避免使用共享状态。有其是多进程。然而,你非得在多进程使用共享数据,multiprocessing提供了几种方来实现。

1、Shared memory共享内存

数据可以存储在共享内存里使用Value或Array。例如,如下代码:

 

posted @ 2017-06-28 09:56  skiler  阅读(367)  评论(0编辑  收藏  举报