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