今天使用Pool使用Queue来传递数据的时候报错:
Queue objects should only be shared between processes through inheritance
后来研究了一下发现网上的教程大部分是要求用mp包里的Manager来构建一个proxy来使用Queue,但其实解决这个错误不一定需要使用Manager.Queue,这个错误报错的地方其实是在fork的时候,把Queue对象作为参数传进给子进程导致的错误。所以使用继承的方式来传递这个对象就可以了。
这里介绍一下Python的三种共享对象的方式:
共享方式 | 支持的类型 |
---|---|
Shared memory | ctypes当中的类型,通过RawValue,RawArray等包装类提供 |
Inheritance | 系统内核对象,以及基于这些对象实现的对象。包括Pipe, Queue, JoinableQueue, 同步对象(Semaphore, Lock, RLock, Condition, Event等等) |
Server process | 有对象,可能需要自己手工提供代理对象(Proxy) |
如果使用Manager.Queue就是使用第三种Server process方式来共享对象啦,但是直接使用第一种Shared memory方式来共享对象会更简单。
所以解决方法很简单,在所有进程Pool可以访问的代码块中新建一个Queue就OK了,这样所有进程在fork的时候复制到的资源描述符其实都是直接指向主进程穿件的Queue的,而且同时这些进程也是他们的子进程,所以可以访问Queue而且也不会报错。
网友评论