一、概述
我们知道不同进程之间内存是不共享的,要想实现两个进程间的通信,咋办呢?我们用什么知识来解决呐?今天就来说说进程间的通信。
二、前戏
之前我们说了queue,这个是线程queue,它的主要目的是两个线程之间的数据,一个是生产者,一个是消费者的模型,而且你必须是线程。只能在这个主线程内的其他线程访问,出了这个进程,你就不能被访问了。
2.1、进程访问queue
from multiprocessing import Process
import queue
def f(qq):
qq.put([42, None, 'hello'])
if __name__ == '__main__':
q = queue.Queue() #把这个q传给了子进程
p = Process(target=f, args=(q,)) #子进程访问父进程的q
p.start()
print(q.get())
p.join()
很明显上面的代码报错,报错如下:
2.2、线程访问queue
import queue,threading
def f(qq):
qq.put([42, None, 'hello'])
if __name__ == '__main__':
q = queue.Queue() #把这个q传给了子线程
p = threading.Thread(target=f, args=(q,)) #子线程访问父线程的q
p.start()
print(q.get())
p.join()
#输出
[42, None, 'hello']
很明显是可以的。由此得出,线程queue传给子进程是不可以的,你以为传给它了,其实传不了,如果你想传的话,必须是进程Queue。
三、进程间数据通信
3.1、Queue
说明:这个Queue是用于进程之间的数据通信,使用方法跟threading里的queue差不多。
from multiprocessing import Process,Queue #导入进程和Queue
def f(qq):
qq.put([42, None, 'hello'])
if __name__ == '__main__':
q = Queue() #把这个q传给了子进程
p = Process(target=f, args=(q,)) #子进程访问父进程的q
p.start()
print(q.get())
p.join()
#输出
[42, None, 'hello']
提问:父进程的q是怎么传给子进程的?
父进程相当于克隆一个Q,把自己的Q克隆了一份交给子进程,子进程这个时候往Q里面放了一份数据,然后父进程又能实际的获取到。但是你克隆了一份是不是就和父进程没有关系了,为什么还能联系在一起呢?但是实际上:等于这两个Q里面的数据又把它序列化了,序列化到一个中间的地方,类似于翻译,然后反序列化给这个父进程这边来了,其实这两个Q就是通过pickle来序列化的,不是一个真正的Q。
小结:
两个线程之间可以修改一个数据,不加锁,可能就会出错。现在进程中的Queue,是实现了数据的传递,不是在修改同一份数据,只是实现一个进程的数据传给了另外一个进程。