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

Python multiprocessing.Process object with multiprocessing.Manager creates multiple multiprocessing forks in Windows Task Manager

我在 运行 宁 python 3.4.3 Windows 标准嵌入式 7。我有一个继承 multiprocessing.Process 的 class。

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

在查看任务管理器时,特别是命令行列,当实例化进程 class 时,我看到 'from.multiprocessing.spawn import spawn_main(parent_pid=XXXX, pipe_handle=XXXX)"" --multiprocessing-fork'.

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

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

感谢您的任何见解。 post 如果有帮助的话,我想我会更笼统地问这是否是预期的行为。

编辑

抱歉,我花了一些测试代码来演示我所看到的行为。不幸的是,我没有提到我还向进程对象传递了一个 multiprocessing.Manager 命名空间对象。下面的代码演示了我认为应该发生的情况,子进程中产生了多个线程,任务管理器中只显示了一个多进程分支。

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 对象,我会看到生成了两个多处理分支。为什么 multiprocessing.Manager() / Namespace() 包含在进程对象中会发生这种情况?

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

Managers provide a way to create data which can be shared between different processes. A manager object controls a server process which manages shared objects. Other processes can access the shared objects by using proxies.

所以,你看到的这两个过程是意料之中的;一个是您的 multiprocessing.Process 子类,另一个是 multiprocessing.Manager 服务器进程。

这是一个很容易 overlook-able 的点。

为未来的读者阐述其含义:

如果一个复杂的应用程序使用多个多进程队列、字典和/或列表,并且每次通过调用新的 multiprocess.Manager() 对象来获取它们,它最终会在 "too many" OS 上显示的进程!

我的确实如此;感谢 Dano 在此线程中的输入,问题得到解决!

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