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

时间:2018-06-08 06:50:11

标签: python linux multiprocessing python-daemon

我的问题是我有一个父进程A,我将守护进程线程设置为RPC服务器,如TaskRPCServer(Thread)。然后我想使用Python multiprocessing.Process对象生成子进程。例如:B = Process(),B.start()。 Dese B将具有与A相同的守护程序线程?有没有办法可以强制B没有在A中运行守护程序线程?因为在某些情况下很多进程都会侦听RPC端口。或者如果我的设计错了,我该怎么做呢?谢谢!

1 个答案:

答案 0 :(得分:2)

当你分叉一个孩子时,它只从一个线程开始。这是defined by POSIX 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

请注意,守护程序线程打印12345,父进程的PID,5次,并且没有人打印12346,子进程的PID。

但与此同时,尽管你所询问的问题并不存在,但 有时混淆了fork和线程的问题,{{1} }如Contexts and start methods中所述,为您提供解决这些问题的方法。

multiprocessing保证您的子进程从干净状态转换为线程,互斥锁等。 2 它还可以防止您意外地共享文件句柄。 (第三个选项multiprocessing.set_start_method('forkserver')通常只在您确保代码在Unix和Windows上运行时才需要。)

<子> 1。对于一些非常古老的Unix平台来说,情况可能并非如此,但对于任何支持POSIX线程的macOS,Linux,* BSD等都会如此,至少可以回到2004,可能更早,但我可以&# 39;在任何地方找到免费且合法的旧POSIX / SUS规格......

<子> 2。除了POSIX文档警告的问题之外,在从后台线程进行多处理时尝试运行Cocoa主循环等问题也存在较为棘手的问题。