一、多进程multiprocessing
multiprocessing是一个程序包,它使用类似于线程模块的API支持生成程序。 多处理程序包同时提供本地和远程并发性,通过使用子进程而不是线程来有效地避开全局解释器锁。 因此,多处理模块允许程序员充分利用给定机器上的多个处理器。 它可以在Unix和Windows上运行。
import multiprocessing import time def run(name): print("hello %s"%name) time.sleep(2) if __name__=="__main__": for i in range(5): p=multiprocessing.Process(target=run,args=("jehu",)) p.start()
每个进程都有一个父进程,下面这个例子查看一下每个进程的进程ID以及父进程ID:
from multiprocessing import Process import os def info(title): print(title) print('module name:', __name__) print('parent process:', os.getppid()) #打印父进程id print('process id:', os.getpid()) #打印当前进程id print("\n\n") def f(name): info('\033[31;1mfunction f\033[0m') print('hello', name) if __name__ == '__main__': info('\033[32;1mmain process line\033[0m') p = Process(target=f, args=('bob',)) p.start() p.join()
执行结果:
main process line module name: __main__ parent process: 7944 process id: 6744 function f module name: __mp_main__ parent process: 6744 process id: 10136 hello bob
主进程的进程id是其子进程的父进程id
进程间通讯
不同进程间内存是不共享的,要想实现两个进程间的数据交换,可以用以下方法:
Queues
使用方法跟threading里的queue差不多
from multiprocessing import Process, Queue def f(q): q.put([42, None, 'hello']) #3.子进程往主进程的Queue里传数据 if __name__ == '__main__': q = Queue() #1.在主进程中生成一个进程Queue实例,注意不同于线程的queue p = Process(target=f, args=(q,)) #2.把主进程的Queue当成参数传给子进程 p.start() print(q.get()) # prints "[42, None, 'hello']" #4.主进程从Queue中取出子进程传进的数据,实现了不同进程之间的数据传递 p.join()
我们知道不同进程间的数据无法共享,是不同的内存空间,那为什么主进程能把queue传给子进程呢?
实际上底层逻辑是,主进程在把queue当作参数传给子进程的时候,实际上是克隆了一个queue给子进程,也就是主进程和子进程各有一个queue,子进程在往它的queue中传数据的时候,有一个第三方把子进程queue中的数据通过pickl序列化存进来,再反序列化写入主进程的queue。有一个第三方,而不是主进程与子进程之间直接传递数据。
from multiprocessing import Process, Queue
def f(q):
q.put([42, None, 'hello']) #3.子进程往主进程的Queue里传数据
if __name__ == '__main__':
q = Queue() #1.在主进程中生成一个进程Queue实例,注意不同于线程的queue
p = Process(target=f, args=(q,)) #2.把主进程的Queue当成参数传给子进程
p.start()
print(q.get()) # prints "[42, None, 'hello']" #4.主进程从Queue中取出子进程传进的数据,实现了不同进程之间的数据传递
p.join()