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
我在 运行 宁 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