multiprocessing.Process 目标只执行了 3 次中的 2 次

multiprocessing.Process target executing only 2 out of 3 times

我正在使用多处理库与主程序并行启动 Process。我在初始化时使用 target 参数来指定要执行的函数。但是该功能大约有 3 次中有 1 次没有执行。

在深入研究多处理库并使用猴子补丁进行调试后,我发现 BaseProcess 的方法 _bootstrapProcess class 继承自 BaseProcess), 应该在初始化时调用目标参数中指定的函数,在调用 Process 的方法 start() 时没有被调用。

因为我的OS是Ubuntu18.04,所以默认的启动方法是fork。所以用于启动进程的 Popen 在 multiprocessing 库的文件 popen_fork.py 中。而在这个Popenclass中,方法_launch是调用os.fork(),然后调用Process的_bootstrap方法。

用猴子补丁,发现子进程中应该执行的代码根本没有执行,这就是为什么在初始化进程时target参数中指定的函数是调用方法 start() 时未执行。

不可能在比我正在处理的环境更简单的环境中重现该问题。但是这里有一些代码代表我在做什么,我的问题是什么:

import time
from multiprocessing import Process
from multiprocessing.managers import BaseManager


class A:

    def __init__(self, manager):
        # manager is an object created by registering it in
        # multiprocessing.managers.BaseManager, so it is made for interprocess
        # communication
        self.manager = manager

        self.p = Process(target=self.process_method, args=(self.manager, ))

    def start(self):
        self.p.start()

    def process_method(self, manager):
        # This is the method that is not executed 2 out of 3 times
        print("(A.process_method) Entering method")
        c = 0
        while True:
            print(f"(A.process_method) Sending message : c = {c}")
            manager.on_reception(f"c = {c}")
            time.sleep(5)


class Manager:

    def __init__(self):
        self.msg = None
        self.unread_msg = False

    def on_reception(self, msg):
        self.msg = msg
        self.unread_msg = True

    def get_last_msg(self):
        if self.unread_msg:
            self.unread_msg = False
            return self.msg
        else:
            return None



if __name__ == "__main__":
    BaseManager.register("Manager", Manager)
    bm = BaseManager()
    bm.start()
    manager = bm.Manager()

    a = A(manager)
    a.start()
    while True:
        msg = manager.get_last_msg()
        if msg is not None:
            print(msg)

每次应该执行的方法是A.process_method。在这个例子中,每次都执行,但在我的环境中,它不是。

有没有人遇到过这个问题并且知道如何解决它?

深入挖掘后,我发现 Flask 服务器是在线程中启动的,而不是在进程中启动的。我在进程中将其更改为 运行 而不是线程,现在一切都如预期的那样 运行ning 。

Flask 和我的进程都在使用日志包。这可能会导致 deadlock when launching a new Process.