具有multiprocessing.Manager的Python multiprocessing.Process对象在Windows任务管理器中创建多个多处理分支

时间:2015-04-30 14:48:24

标签: python multiprocessing

我正在Windows Standard Embedded 7上运行python 3.4.3。我有一个继承multiprocessing.Process的类。

在类的run方法中,我为进程对象创建了一个线程来启动。

在观察任务管理器,特别是命令行列时,当实例化进程类时,我看到' from.multiprocessing.spawn导入spawn_main(parent_pid = XXXX,pipe_handle = XXXX)"&#34 ; --multiprocessing叉'

当进程中的线程启动时,我会看到来自同一父进程id的另一个pythonw.exe多处理分支。当线程完成时,单独的进程结束。

为什么在单独的进程中创建线程会导致另一个多处理fork生成?

感谢您的任何见解。如果有帮助的话,会发布,但是如果这是预期的行为,我会更一般地问。

修改

很抱歉,我们花了一些时间对一些测试代码进行了演示,以展示我所看到的行为。不幸的是,我忽略了提到我还将一个multiprocessing.Manager Namespace对象传递给了进程对象。下面的代码演示了我认为应该发生的事情,多个线程在子进程中生成,并且在任务管理器中只显示一个多处理分支。

import multiprocessing
import threading
import time

class Comm(multiprocessing.Process):
    def __init__(self):#, namespace=None):
        multiprocessing.Process.__init__(self)
        #self.namespace=namespace
        self.comm_queue=multiprocessing.Queue()

    def talk(self):
        counter=0
        while counter != 4:
            self.comm_queue.put('i am talking')
            time.sleep(2)
            counter += 1

    def yell(self):
        counter=0
        while counter != 3:
            self.comm_queue.put('I AM YELLING')
            time.sleep(5)
            counter += 1

    def make_threads(self):
        self.talk_thread=threading.Thread(target=self.talk)
        self.yell_thread=threading.Thread(target=self.yell)


    def run(self):
        self.make_threads()
        self.talk_thread.start()
        self.yell_thread.start()
        while True:
            time.sleep(1)


if __name__=='__main__':
    #test_manager=multiprocessing.Manager()
    #test_ns=test_manager.Namespace()
    test=Comm()#namespace=test_ns)
    test.start()
    while True:
        message=test.comm_queue.get()
        print(message)

但是,如果取消注释所有内容并传入Namespace对象,我会看到两个多处理分叉spawn。为什么在multiprocessing.Manager()/ Namespace()包含在进程对象中会发生这种情况?

2 个答案:

答案 0 :(得分:2)

multiprocessing.Manager通过生成单独的Manager服务器进程来运行,该进程将一直运行直到Manager被垃圾回收:

  

管理员提供了一种创建可在其间共享的数据的方法   不同的过程。管理器对象控制服务器进程   管理共享对象。其他进程可以访问共享对象   通过使用代理。

所以,你看到的两个过程是预期的;一个是你的multiprocessing.Process子类,另一个是multiprocessing.Manager服务器进程。

答案 1 :(得分:0)

这是一个容易被忽视的观点。

详细说明未来读者的含义:

如果复杂的应用程序使用多个多进程队列,dicts和/或列表,并且每次通过调用新的multiprocess.Manager()对象获取它们,它将最终出现在“太多”进程中OS!

它在我的;感谢Dano在这个帖子中的意见,这个问题得到了解决!

从共享的multiprocess.Manager()获取dicts时,从Py 361开始,要注意的一个值得注意的问题是:https://bugs.python.org/issue30256