day9-进程间数据交互
概述
我们知道不同进程之间内存是不共享的,进程与进程间是相互独立的,如果一定要实现进程间的数据交换,那么应该如何实现呢?
实现方法
1.进程Queue
这里的进程queue和之前生产者消费者模型里面的线程queue有明显的区别:
线程间是共享内存的,所以线程间可以互相访问
import threading import queue #子线程 def f(): q.put([42, None, 'hello']) #往主线程队列里面put数据 #主线程 if __name__ == '__main__': q = queue.Queue() #生成一个队列实例 p = threading.Thread(target=f,) #生成一个线程实例 p.start() print("队列大小为:",q.qsize()) print(q.get()) # prints "[42, None, 'hello']" p.join() #运行输出 队列大小为:1 [42, None, 'hello'] Process finished with exit code 0
进程间是内存不共享的,也就是说,出了这个进程,别的进程就不能访问了
from multiprocessing import Process import queue #子进程 def f(): q.put([42, None, 'hello']) #往父进程队列里面put数据 #父进程 if __name__ == '__main__': q = queue.Queue() #生成一个队列实例 p = Process(target=f,) # p.start() print(q.get()) # prints "[42, None, 'hello']" p.join() #运行输出 队列大小为:0
解析:因为队列对象q是在父进程里面启动的,同时,子进程f也是通过父进程p进行启动的,但是启动后,子进程和父进程的内存都是独立的了,双方就没有关系了,既然是独立的了,那么在这种情况下,父进程里面的q,子进程是访问不了的,所以父进程的队列为0。其次把一个线程queue从父进程传给子进程,其实也是传不了的,所以只能使用进程queue进行进程间的queue的传递。
#进程间的queue from multiprocessing import Process,Queue #子进程 def f(q1): q1.put([42, None, 'hello']) #往父进程队列里面put数据 #父进程 if __name__ == '__main__': q = Queue() #生成一个队列实例 p = Process(target=f,args=(q,)) #将生成的队列对象传给了子进程对象 p.start() print(q.get()) # prints "[42, None, 'hello']" p.join() #运行输出 [42, None, 'hello'] Process finished with exit code 0
解析:从得出的结果可以看出,进程间实现了共享的queue数据,其实不是的,首先父进程创建了子进程后,父进程克隆了一个相同的queue交给了子进程,子进程往克隆的queue里面存放了数据,这就产生了2个queue(实际上是父进程的queue和子进程的克隆queue,2个独立的queue),那么他们之间是如何进行通信的呢?如何实现数据的共享?实际上通过pickle将子进程的queue数据序列化通过中间方传递给父进程后,又被反序列化为父进程的queue,所以父进程可以取出子进程中的数据。
小结
queue用来在进程间传递消息,任何可以pickle的对象都可以加入到queue