多进程
1、使用multiprocessing 模块创建多进程
Process
Process类描述一个进程对象,创建Process实例只需要传入一个函数和函数的参数即可。
- 使用 Process() 方法创建进程
- 使用 start() 方法启动进程
- 使用 join() 方法实现进程同步
一个例子:
# coding=utf8
import os
from multiprocessing import Process
def run_proc(name):
print 'child process %s (%s) running...' %(name, os.getpid())
if __name__ == '__main__':
print 'Parent process is %s.' % os.getpid()
for i in range(5):
p = Process(target=run_proc, args=(str(i),))
print 'process will start'
p.start()
p.join()
print 'main process end'
Pool
Pool类描述一个进程池对象,可以提供指定数量的进程共用户调用,默认大小是CPU的核数。
一个例子:
# coding=utf8
from multiprocessing import Pool
import os, time, random
def run_task(name):
print 'Task %s (pid = %s) is running...' % (name, os.getpid())
time.sleep(random.random() * 3)
print 'Task %s end.' % name
if __name__ == '__main__':
print 'Current process %s.' % os.getpid()
p = Pool(processes=3)
for i in range(5):
p.apply_async(run_task, args=(i,))
print 'Waiting for all subprocesses done...'
p.close() # 调用join()之前先必须调用close(),调用close()之后就不会继续添加新的Process了
p.join()
print 'All subprocesses done.'
2、进程间通信
Queue
Queue类用来在多个进程间实现通信
- put方法:插入数据到队列中
- get方法:从队列中读取并删除一个元素
一个例子:
# coding=utf8
'''
从父进程创建三个子进程,两个进程往Queue中写数据,一个从Queue中读数据
'''
from multiprocessing import Process, Queue
import os, time, random
from test.test_threading_local import target
# 写进程
def proc_write(q,urls):
print 'Process (%s) is writing...' % os.getpid()
for url in urls:
q.put(url)
print 'Put %s to Queue...' % url
time.sleep(random.random())
# 读进程
def proc_read(q):
print 'Process %s is reading...' % os.getpid()
while True:
url = q.get()
print 'Get %s from queue' % url
if __name__ == '__main__':
q = Queue()
writer1 = Process(target=proc_write, args=(q, ['url_1','url_2','url_3']))
writer2 = Process(target=proc_write, args=(q, ['url_4','url_5','url_6']))
reader = Process(target=proc_read, args=(q,))
# 启动写进程
writer1.start()
writer2.start()
# 启动读进程
reader.start()
# 等待写进程结束
writer1.join()
writer2.join()
# 强制结束读进程
reader.terminate()
Pipe
Pipe类用来在两个进程之间通信,类似于一个管道,Pipe方法返回(conn1,conn2)代表管道两端,参数duplex为True是全双工模式。
一个例子:
# coding=utf8
from multiprocessing import Pipe, Process
import random, time, os
from test.test_threading_local import target
'''
创建两个进程,一个通过Pipe发送数据,一个通过Pipe接收数据
'''
def proc_send(pipe, urls):
for url in urls:
print 'Process (%s) send: %s' % (os.getpid(), url)
pipe.send(url)
time.sleep(random.random())
def proc_recv(pipe):
while True:
print 'Process (%s) recv: %s' % (os.getpid(), pipe.recv())
time.sleep(random.random())
if __name__ == '__main__':
pipe = Pipe()
p1 = Process(target=proc_send, args=(pipe[0], ['url_'+str(i) for i in range(10)]))
p2 = Process(target=proc_recv, args=(pipe[1],))
p1.start()
p2.start()
p1.join()
p2.terminate()