尽管我对此主题的理解有限,但是从我的理解中可以看出multiprocessing.Queue()和multiprocessing.Manager()。Queue()之间有一个主要区别:
- multiprocessing.Queue()是一个对象,而multiprocessing.Manager()。Queue()是指向由multiprocessing.Manager()对象管理的共享队列的地址(代理)。
- 因此您不能将普通的multiprocessing.Queue()对象传递给Pool方法,因为它不能被腌制。
- 此外,python文档告诉我们在使用multiprocessing.Queue()时要特别注意,因为它可能会产生不良影响
注意 将对象放入队列时,将对对象进行酸洗,然后后台线程将酸洗的数据刷新到基础管道。这会带来一些令人惊讶的后果,但不会造成任何实际困难-
如果它们确实困扰您,那么您可以使用由经理创建的队列。将对象放在空队列上之后,在队列的empty()方法返回False且get_nowait()可以不增加Queue.Empty的情况下返回之前,可能会有无穷的延迟。如果多个进程正在排队对象,则有可能在另一端无序接收对象。但是,通过相同过程排队的对象始终相对于彼此处于预期的顺序。警告
如上所述,如果子进程已将项目放入队列中(并且尚未使用JoinableQueue.cancel_join_thread),则该进程将不会终止,直到所有缓冲的项目都已刷新到管道中为止。这意味着,如果您尝试加入该进程,则可能会陷入僵局,除非您确定已放入队列中的所有项目都已消耗完。同样,如果子进程是非守护进程,则当父进程尝试加入其所有非守护进程子进程时,其父进程可能会在退出时挂起。请注意,使用管理器创建的队列不存在此问题。
通过将队列设置为全局变量,并在初始化时为所有进程设置队列,可以将multiprocessing.Queue()与Pool结合使用:
queue = multiprocessing.Queue()def initialize_shared(q): global queue queue=qpool= Pool(nb_process,initializer=initialize_shared, initargs(queue,))
将使用正确共享的队列创建池进程,但是我们可以争辩说不是为此用途创建了multiprocessing.Queue()对象。
另一方面,通过将pool.Manager.Queue()作为函数的常规参数传递,可以在池子进程之间共享manager.Queue()。
我认为,在每种情况下使用multiprocessing.Manager()。Queue()都很好,而且麻烦也较少。使用管理器可能有一些缺点,但我不知道。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)