目录
简介
多进程相对于多线程可以更好的使用多核,避开GIL(Global Interpreter Lock)的影响。而且多进程引入了进程池的概念,可以更好的并行处理不同输入的数据。
Process 类
在多进程中,通过创建Process对象和调用start()函数来生成一个新的进程。Process类似于threading.Thread。
from multiprocessing import Process
import os
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):
info('function f')
print 'hello', name
if __name__ == '__main__':
info('main line')
p = Process(target=f, args=('bob',))
p.start()
p.join()
输出结果为:
main line
module name: __main__
parent process: 9335
process id: 128831
function f
module name: __main__
parent process: 128831
process id: 129413
hello bob
即创建了一个进程,来运行函数。
进程间通信
在python的多进程中,主要有两种通信方式:Queues和Pipes
Queues
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()
p.join()
输出结果:
[42, None, 'hello']
一个简单的进程间通信的列子,writer从已有的queue中读取数据,并将数据加一写入out_queue当中,reader从out_queue当中读取writer写入的数据并将其输出。比较需要注意的是,在multiprocessing中的Queue,包含Queue类的所有功能除了join()和task_done(),所以当需要用到这两个函数的时候,需要使用JoinableQueue()。
import multiprocessing
queue = multiprocessing.JoinableQueue()
out_queue = multiprocessing.JoinableQueue()
class WriterProcess(multiprocessing.Process):
def __init__(self, queue, out_queue):
multiprocessing.Process.__init__(self)
self.queue = queue
self.out_queue = out_queue
def run(self):
while True:
tmp = self.queue.get()
tmp += 1
self.out_queue.put(tmp)
self.queue.task_done()
class ReaderProcess(multiprocessing.Process):
def __init__(self, queue):
multiprocessing.Process.__init__(self)
self.queue = queue
def run(self):
while True:
tmp = self.queue.get()
print tmp
self.queue.task_done()
def main():
for i in range(5):
queue.put(i)
for i in range(3):
pw = WriterProcess(queue, out_queue)
pw.daemon = True
pw.start()
for i in range(2):
pr = ReaderProcess(out_queue)
pr.daemon = True
pr.start()
queue.join()
out_queue.join()
main()
进程间同步
from multiprocessing import Process, Lock
import time
def f(l, i):
l.acquire()
print 'Hello World', i
time.sleep(1)
print i, "end"
l.release()
if __name__ == '__main__':
lock = Lock()
for num in range(10):
Process(target=f, args=(lock, num)).start()
输出结果为:
Hello World 0
0 end
Hello World 1
1 end
Hello World 2
2 end
Hello World 3
3 end
Hello World 4
4 end
Hello World 5
5 end
Hello World 6
6 end
Hello World 7
7 end
Hello World 8
8 end
Hello World 9
9 end
如果不用锁的话,输出结果如下:
Hello World 0
Hello World 1
Hello World 2
Hello World 3
Hello World 4
Hello World 5
Hello World 6
Hello World 7
Hello World 8
Hello World 9
0 end
1 end
3 2end
end
45 end
end
76 endend
89 endend