Python 如果我分叉一个有守护进程线程的进程,会发生什么?

Python 如果我分叉一个有守护进程线程的进程,会发生什么?,python,linux,multiprocessing,python-daemon,Python,Linux,Multiprocessing,Python Daemon,我的问题是我有一个父进程a,并且我设置了一个守护进程线程作为RPC服务器,比如TaskRPCServer(线程)。然后我想使用Python multiprocessing.process对象生成一个子进程。例如:B=Process(),B.start()。Dese B将具有与A相同的守护进程线程?有没有一种方法可以强制B不让守护进程线程在a中运行?因为在某些情况下,很多进程将侦听RPC端口。或者,如果我的设计是错误的,我如何才能正确地做到这一点?谢谢大家! 当你叉一个孩子时,它只从一根线开始。这

我的问题是我有一个父进程a,并且我设置了一个守护进程线程作为RPC服务器,比如TaskRPCServer(线程)。然后我想使用Python multiprocessing.process对象生成一个子进程。例如:B=Process(),B.start()。Dese B将具有与A相同的守护进程线程?有没有一种方法可以强制B不让守护进程线程在a中运行?因为在某些情况下,很多进程将侦听RPC端口。或者,如果我的设计是错误的,我如何才能正确地做到这一点?谢谢大家!

当你叉一个孩子时,它只从一根线开始。这是:1

应使用单个线程创建进程。如果多线程进程调用fork(),则新进程应包含调用线程及其整个地址空间的副本,可能包括互斥体和其他资源的状态

因此,您的子进程将没有守护进程线程。你不必做任何事来强迫它不要这样做


您可以很容易地自己测试这一点:

import threading
import os
import time

def threadfunc():
    while True:
        print(os.getpid())
        time.sleep(1)

def main():
    t = threading.Thread(target=threadfunc)
    t.start()
    pid = os.fork()
    if pid:
        print(f'Forked {pid}; sleep time')
        time.sleep(5)
    else:
        print(f'Forked child; sleep time')
        time.sleep(5)

main()
如果运行此命令,您将看到如下内容:

12345
Forked 12346; sleep time
Forked child; sleep time
12345
12345
12345
请注意,守护进程线程打印了5次父进程的PID 12345,但没有人打印过子进程的PID 12346


但与此同时,即使您所问的问题不存在,有时也会出现混合
fork
和线程的问题,
多处理
为您提供了解决这些问题的方法,如中所述

多处理。set_start_method('forkserver')
保证您的子进程在线程、互斥体等方面处于干净状态。2它还可以防止您意外共享文件句柄。(第三个选项,
spawn
,通常仅当您希望确保代码在Unix和Windows上运行时才需要。)


一,。对于一些非常古老的Unix平台来说,这可能不是真的,但对于任何支持POSIX线程的macOS、Linux、*BSD等都是真的。至少支持POSIX线程,可能支持更早的版本,但我在任何地方都找不到免费且合法的旧POSIX/SUS规范


二,。除了POSIX文档警告的问题之外,还有一些更为模糊的问题,比如在从后台线程进行多处理时尝试运行Cocoa主循环。

当您分叉一个子线程时,它只从一个线程开始。这是:1

应使用单个线程创建进程。如果多线程进程调用fork(),则新进程应包含调用线程及其整个地址空间的副本,可能包括互斥体和其他资源的状态

因此,您的子进程将没有守护进程线程。你不必做任何事来强迫它不要这样做


您可以很容易地自己测试这一点:

import threading
import os
import time

def threadfunc():
    while True:
        print(os.getpid())
        time.sleep(1)

def main():
    t = threading.Thread(target=threadfunc)
    t.start()
    pid = os.fork()
    if pid:
        print(f'Forked {pid}; sleep time')
        time.sleep(5)
    else:
        print(f'Forked child; sleep time')
        time.sleep(5)

main()
如果运行此命令,您将看到如下内容:

12345
Forked 12346; sleep time
Forked child; sleep time
12345
12345
12345
请注意,守护进程线程打印了5次父进程的PID 12345,但没有人打印过子进程的PID 12346


但与此同时,即使您所问的问题不存在,有时也会出现混合
fork
和线程的问题,
多处理
为您提供了解决这些问题的方法,如中所述

多处理。set_start_method('forkserver')
保证您的子进程在线程、互斥体等方面处于干净状态。2它还可以防止您意外共享文件句柄。(第三个选项,
spawn
,通常仅当您希望确保代码在Unix和Windows上运行时才需要。)


一,。对于一些非常古老的Unix平台来说,这可能不是真的,但对于任何支持POSIX线程的macOS、Linux、*BSD等都是真的。至少支持POSIX线程,可能支持更早的版本,但我在任何地方都找不到免费且合法的旧POSIX/SUS规范

二,。除了POSIX文档警告的问题之外,还有一些更为模糊的问题,比如在从后台线程进行多处理时尝试运行Cocoa主循环