为什么 Python 子进程 "inherit" 来自父进程的线程?

Why does Python subprocess "inherit" the threads from the parent process?

我是 Python 3 multiprocessing 模块的新手,可能似乎误解了其中一个概念。在我的应用程序中,我像往常一样有主线程,还有另一个线程用于一些“后台”工作,称为“BgThread”。在第二个线程中,我通过 start().

生成了 Process 和 运行

新的子进程现在可以正确启动并执行其工作。但是,当我在 (VS Code) 调试器中查看我的应用程序时,我可以看到该子进程也有第二个线程 运行ning,再次称为“BgThread”。

运行 on Linux 我尝试通过 mp.set_start_method("spawn") 生成线程,如多处理文档中所述,但结果相同。此外,当我在第二个线程 class 的 run() 方法中设置断点时,在子进程中它不会停在那里(但它在主进程中这样做是正确的)。

这是正常行为吗?如果是这样,那么我不明白 - 为什么子进程也从其父进程继承这个第二个线程,即使它似乎并没有像上面描述的那样真正再次启动它?是否需要阻止我的子进程再次启动第二个线程?

正如@AndriiMaletskyi 评论的那样,您看到的一定是调试器引入的一些奇怪结果。下面的程序运行在Linux下使用spawn启动新进程,首先创建一个线程,然后启动一个进程。该线程被传递一个 multiprocessing.Value 实例,该实例在一个循环中递增 5 次,在该循环中它还打印出一条消息。如果子进程继承了这个线程,我们希望看到打印出超过 5 条消息,并且这个 multiprocessing.Value 实例的最终值大于 5。此外,为了更好的衡量,子进程枚举它的线程并且只有一。如果它从主进程继承了线程,那么如果不是三个,则至少 两个。

from multiprocessing import Process, Value, set_start_method
from os import getpid
import threading
import time

def worker(*args):
    first_time = True
    for x, y in args:
        time.sleep(1.1)
        print(f'{x} + {y} = {x + y}')
        if first_time:
            first_time = False
            for thread in threading.enumerate():
                print('thread:', thread.name)

def my_thread(v):
    for counter in range(1, 6):
        print(f'time: {time.time()}, counter: {counter}, process id: {getpid()}, thread id: {threading.get_ident()}')
        with v.get_lock():
            v.value += 1
        time.sleep(1)

if __name__ == '__main__':
    set_start_method("spawn")
    v = Value('i', 0, lock=True)
    t = threading.Thread(target=my_thread, args=(v,))
    t.start()
    args = ((1, 2), (3, 4), (4, 5), (6,7))
    p = Process(target=worker, args=args)
    p.start()
    p.join()
    t.join()
    print('Value =', v.value)

打印:

time: 1637499015.9222672, counter: 1, process id: 33, thread id: 139689716135680
time: 1637499016.9244416, counter: 2, process id: 33, thread id: 139689716135680
1 + 2 = 3
thread: MainThread
time: 1637499017.925643, counter: 3, process id: 33, thread id: 139689716135680
3 + 4 = 7
time: 1637499018.926832, counter: 4, process id: 33, thread id: 139689716135680
4 + 5 = 9
time: 1637499019.9280066, counter: 5, process id: 33, thread id: 139689716135680
6 + 7 = 13
Value = 5