day10 -进程间数据的交换

一、概述

  我们知道不同进程之间内存是不能共享的,要想实现进程间的数据通讯,怎么搞呢,请看下面,

类似,中间需要有一个翻译,例如:一个英国人,一个中国人,需要有一个会说中文,又会说英语的人做翻译。

二、前戏

  之前我们说了queue,这个是线程queue,它的主要目的是两个线程之间的数据,一个是生产者,一个是消费者的模型,而且你必须是线程。只能在这个主线程内的其他线程访问,出了这个进程,你就不能被访问了。

2.1、进程访问queue

 1 from multiprocessing import Process
 2 import queue
 3 
 4 def f(pq):
 5     q.put("niubi")
 6 
 7 if __name__ == "__main__":
 8     q=queue.Queue()
 9     p=Process(target=f,args=(q,))
10     p.start()
11     print(q.get())
12     p.join()
13 
14 ===出错信息
15 D:\51cto\venv\Scripts\python.exe "D:/51cto/day 10/tq&pq.py"
16 Traceback (most recent call last):
17   File "D:/51cto/day 10/tq&pq.py", line 11, in <module>
18     p.start()
19   File "d:\ProgramData\Anaconda3\Lib\multiprocessing\process.py", line 105, in start
20     self._popen = self._Popen(self)
21   File "d:\ProgramData\Anaconda3\Lib\multiprocessing\context.py", line 223, in _Popen
22     return _default_context.get_context().Process._Popen(process_obj)
23   File "d:\ProgramData\Anaconda3\Lib\multiprocessing\context.py", line 322, in _Popen
24     return Popen(process_obj)
25   File "d:\ProgramData\Anaconda3\Lib\multiprocessing\popen_spawn_win32.py", line 65, in __init__
26     reduction.dump(process_obj, to_child)
27   File "d:\ProgramData\Anaconda3\Lib\multiprocessing\reduction.py", line 60, in dump
28     ForkingPickler(file, protocol).dump(obj)
29 TypeError: can't pickle _thread.lock objects


2.2、线程Q

 1 import threading,queue
 2 
 3 
 4 def f(tt):
 5     q.put("niubi")
 6 
 7 if __name__ == '__main__':
 8     q=queue.Queue()
 9     p=threading.Thread(target=f,args=(q,))
10     p.start()
11     print(q.get())
12     p.join()

很明显是可以的。由此得出,线程queue传给子进程是不可以的,你以为传给它了,其实传不了,如果你想传的话,必须是进程Queue。

三、进程Q,进程间的通讯

说明:这个Queue是用于进程之间的数据通信,使用方法跟threading里的queue差不多。

 1 from multiprocessing import Process
 2 from multiprocessing import Queue
 3 
 4 def f(pq):
 5     pq.put("niubi")
 6 
 7 if __name__ == '__main__':
 8 
 9     q  = Queue()
10     p=Process(target=f,args=(q,))
11     p.start()
12     print(q.get())
13     p.join()

提问:父进程的q是怎么传给子进程的?

  父进程相当于克隆一个Q,把自己的Q克隆了一份交给子进程,子进程这个时候往Q里面放了一份数据,然后父进程又能实际的获取到。但是你克隆了一份是不是就和父进程没有关系了,为什么还能联系在一起呢?但是实际上:等于这两个Q里面的数据又把它序列化了,序列化到一个中间的地方,类似于翻译,然后反序列化给这个父进程这边来了,其实这两个Q就是通过pickle来序列化的,不是一个真正的Q。

小结:

  两个线程之间可以修改一个数据,不加锁,可能就会出错。现在进程中的Queue,是实现了数据的传递,不是在修改同一份数据,只是实现一个进程的数据传给了另外一个进程。

posted @ 2018-03-21 11:32  东郭仔  阅读(231)  评论(0)    收藏  举报