我正在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()包含在进程对象中会发生这种情况?
答案 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