Value 和 Array实现的数据共享的数据类型只支持数值,字符和数组这些简单的,而Manager函数能支持的作为数据共享的数据类型有很多,最常用的就是列表和字典
In [22]: help(multiprocessing.Manager) Help on function Manager in module multiprocessing: Manager() Returns a manager associated with a running server process The managers methods such as `Lock()`, `Condition()` and `Queue()` can be used to create shared objects.
例子:
[root@web thread_process]# cat multi6.py #!/usr/bin/env python import multiprocessing def worker(d, l): for i in xrange(5): key = 'key{0}'.format(i) value = 'value{0}'.format(i) d[key] = value l += range(5) if __name__ == '__main__': manager = multiprocessing.Manager() dic = manager.dict() l = manager.list() print dic print l p = multiprocessing.Process(target=worker, args=(dic, l)) p.start() p.join() print '#######################' print dic print l [root@web thread_process]# python multi6.py {} [] ####################### {'key3': 'value3', 'key2': 'value2', 'key1': 'value1', 'key0': 'value0', 'key4': 'value4'} [0, 1, 2, 3, 4]
进程池:
进程池(multiprocessing.Pool)是multiprocessing的一个类,可以同时自动处理几百上千个并行操作
进程池的用法:
当有新的请求提交到pool中,如果池还没满,会创建一个新的子进程用来执行该请求;如果池中的子进程已达到processes的值,那么该请求会一直等待直到池中有子进程结束,才会创建新的子进程来处理它
In [3]: help(multiprocessing.Pool) Help on function Pool in module multiprocessing: Pool(processes=None, initializer=None, initargs=()) Returns a process pool object //返回一个进程池对象 pool = multiprocessing.Pool(processes=3) //实例化一个对象,processes=3表示进程池能同时最多创建3个子进程执行任务 //默认processes=None,表示cpu核数是多少,最大进程数就是多少 result = pool.apply_async(func=task, args=(i,)) //向进程池提交目标请求,也就是子进程以多进程方式执行task()函数,非阻塞的;但是result.get()方法是阻塞的 pool.close() //等待池中的子进程执行结束再关闭pool pool.terminate() //直接关闭pool pool.join() //等待池中的子进程执行完毕,用于阻塞主进程,否则主进程结束,进程池里的进程也会结束 //必须用在pool.close()或者pool.terminate()之后
进程池原理解析:
[root@web thread_process]# cat pool1.py #!/usr/bin/env python import multiprocessing from subprocess import Popen, PIPE def task(i): p = Popen(['vim'], stdout=PIPE, stderr=PIPE) p.communicate() //不输出结果,静默等待命令执行完毕 print 'Task id: %s' i pool = multiprocessing.Pool(processes=2) //进程池最多同时运行2个进程 for i in xrange(5): //产生五个子进程 pool.apply_async(func=task, args=(i,)) print 'Waitting.....' //由于pool.apply_async()是非阻塞的,所以就算进程池里的进程没有执行完毕仍然会执行主进程的内容 pool.close() //等待池中处理完5个请求才关闭进程池 pool.join() //阻塞主进程,让其等待线程池进程执行完毕 print 'Finished!'
例子:
[root@web thread_process]# cat pool2.py #!/usr/bin/env python import multiprocessing import os import time def task(i): print 'Task id: %s pid(%s) parent pid(%s)' % (i, os.getpid(), os.getppid()) time.sleep(1) pool = multiprocessing.Pool() //注意:processes的值是可以比cpu核数更大的 print 'Parent process id: %s' %os.getpid() for i in xrange(6): pool.apply_async(func=task, args=(i,)) print 'Waitting.....' pool.close() pool.join() print 'Finished!' [root@web thread_process]# python pool2.py Parent process id: 20919 Waitting..... Task id: 0 pid(20922) parent pid(20919) Task id: 1 pid(20921) parent pid(20919) Task id: 2 pid(20920) parent pid(20919) Task id: 3 pid(20923) parent pid(20919) Task id: 4 pid(20921) parent pid(20919) Task id: 5 pid(20920) parent pid(20919) Finished!