multiprocessing在python2.6+版本中得到应用。
multi意思为多个,processing意思为进程 也就是实现多进程。可以实现利用调用计算机的多个CPU实现多线程。
multiprocessing是一个包,支持使用类似threading模块的API生成进程。multiprocessing包提供本地和远程两种并发,通过使用子进程而非线程有效地回避了全局解释器锁。 因此,multiprocessing模块允许程序员充分利用一个给定机器的多个处理器。它在Unix和Windows上都可允许。
下面主要介绍进程类:
线程是通过创建Process对象,然后调用start()方法来产生的。Process继承了threading.Thread的API。现在举一个multiprocess 的例子:
使用Process创建进程:
from multiprocessing import Process
def f(name):
print ‘hello‘, name
if __name__ == ‘__main__‘:
p = Process(target=f, args=(‘bob‘,)) #创建一个线程
p.start() #调用start方法 启动
p.join()
下面是一个活的线程ID的例子:
from multiprocessing import Process
import os
def info(title):
print title
print ‘module name:‘, __name__
if hasattr(os, ‘getppid‘): # 只在Unix中可使用
print ‘parent process:‘, os.getppid()
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()
代码中使用os的getpid()获得父进程的ID 使用getip()获得当前进程的ID,另外还可以使用getppid获得父进程的父进程的ID。
IPC(Inter-Process Communication) 进程间的通信
multiprocessing包中有Pipe类和Queue类来分别支持这两种IPC机制。Pipe和Queue可以用来传送常见的对象。
Pipe可以是单向(half-duplex),也可以是双向(duplex)。我们通过mutiprocessing.Pipe(duplex=False)创建单向管道 (默认为双向)。一个进程从PIPE一端输入对象,然后被PIPE另一端的进程接收,单向管道只允许管道一端的进程输入,而双向管道则允许从两端输入。
举例:(单向的)
from multiprocessing import Process, Pipe
def f(conn): #conn为父线程传递过来的pipe对象
conn.send([42, None, ‘hello‘]) #在pipe对象的一端发送数据
conn.close() #关闭
if __name__ == ‘__main__‘:
parent_conn, child_conn = Pipe() #定义两个Pipe对象来创建
p = Process(target=f, args=(child_conn,))#创建一个进程 传递的参数为pipe对象
p.start()
print parent_conn.recv() # prints "[42, None, ‘hello‘]" #在父进程中使用另一个pipe对象的recv()方法接受数据
p.join()
每个连接对象都有send和recv方法,需要注意的是,如果两个进程或者线程同时读取或写入pipe对象的终端,则可能引起终端。如果同时使用pipe的不同终端则不会有风险。
下面举例:(双向)
import multiprocessing as mul
def proc1(pipe):
pipe.send(‘hello‘)
print(‘proc1 rec:‘,pipe.recv())
def proc2(pipe):
print(‘proc2 rec:‘,pipe.recv())
pipe.send(‘hello, too‘)
if __name__ == ‘__main__‘:
mul.freeze_support()
pipe1,pipe2= mul.Pipe() #创建两个pipe对象
# Pass an end of the pipe to process 1
p1 = mul.Process(target=proc1, args=(pipe1,)) #创建p1线程
# Pass the other end of the pipe to process 2
p2 = mul.Process(target=proc2, args=(pipe2,)) #创建p2线程
p1.start() #调用线程1
p2.start() #调用线程2
p1.join() #这里等待线程1执行完成
p2.join() #等待线程2执行完成
#输出:
(‘proc2 rec:‘, ‘hello‘)
(‘proc1 rec:‘, ‘hello, too‘)
这个例子实现了两个线程之间的通信,实现了双向通信。线程1: proc1中发送”hello”字符串,线程proc2中接收线程1proc1中发送的”hello”字符串并输出,然后proc2发送”hello, too”字符串,线程1 proc1接收到proc2发送的字符串并输出。
下面介绍另外一种实现IPC的方式:
Queue:
Queue与Pipe相类似,都是先进先出的结构。但Queue允许多个进程放入,多个进程从队列取出对象。Queue使用mutiprocessing.Queue(maxsize)创建,maxsize表示队列中可以存放对象的最大数量。
下面的程序展示了Queue的使用:
from multiprocessing import Process, Queue
def f(q):
q.put([42, None, ‘hello‘]) #调用主函数中p进程传递过来的进程参数 put函数为向队列中添加一条数据。
if __name__ == ‘__main__‘:
q = Queue() #创建一个Queue对象
p = Process(target=f, args=(q,)) #创建一个进程
p.start()
print q.get() # prints "[42, None, ‘hello‘]"
p.join()
上面是一个queue的简单应用,使用队列q对象调用get函数来取得队列中最先进入的数据。
举一个复杂些的例子:
import multiprocessing
import time
# 向queue中输入数据的函数
def inputQ(queue):
info = str(os.getpid()) + ‘(put):‘ + str(time.time())
queue.put(info)
# 向queue中输出数据的函数
def outputQ(queue,lock):
info = queue.get()
lock.acquire()
print (str(os.getpid()) + ‘(get):‘ + info)
lock.release()
# Main
if __name__ == ‘__main__‘:
multiprocessing.freeze_support()
record1 = [] # store input processes
record2 = [] # store output processes
lock = multiprocessing.Lock() #使用锁方法输出错乱
queue = multiprocessing.Queue(3)
# 输入进程
for i in range(10):
process = multiprocessing.Process(target=inputQ,args=(queue,))
process.start()
record1.append(process)
# 输出进程
for i in range(10):
process = multiprocessing.Process(target=outputQ,args=(queue,lock))
process.start()
record2.append(process)
for p in record1:
p.join()
queue.close() # 如果没有数据进入队列中则关闭队列
for p in record2:
p.join()
#输出结果为:
15212(get):7180(put):1440649672.22
8820(get):7020(put):1440649672.85
6164(get):7872(put):1440649673.39
10904(get):9436(put):1440649673.68
5016(get):16840(put):1440649674.07
12004(get):12848(put):1440649674.38
14456(get):11608(put):1440649674.66
2468(get):16884(put):1440649674.85
6464(get):8944(put):1440649674.89
7576(get):15476(put):1440649674.92
这个例子中,创建了二十个进程,十个是用来写入队列数据的,另外十个是用来输出队列中的数据的。
版权声明:本文为博主原创文章,未经博主允许不得转载。
multiprocessing 基于进程的“线程式”接口 python
原文地址:http://blog.csdn.net/winterto1990/article/details/48025881