我编写了一个服务器,该服务器在某些端口上侦听传入的请求。当请求到达时,它将派生一个新的守护程序来处理每个请求。我目前使用multiprocessing
库,如下所示:
import multiprocessing as mup
new_worker = mup.Process(target=worker,args=(param,))
new_worker.daemon = True
new_worker.start()
问题是,当我在bash中运行ps
命令时,我发现那些守护程序的状态已失效。这些守护程序的父进程ID PPID也不为1(int的PID)。例如,以下是ps
命令的示例输出:
$ ps axo pid,ppid,pgid,sess,comm --forest | grep -E 'python| PID'
PID PPID PGID SESS COMMAND
28822 25898 28822 25898 | \_ python3
28823 28822 28822 25898 | | \_ python3 <defunct>
28828 28822 28822 25898 | | \_ python3 <defunct>
28831 28822 28822 25898 | | \_ python3 <defunct>
请注意,使用PID 28822的进程是服务器。而带有s {28823,28828,28831}的进程是守护程序。它们以<defunct>
的形式保留。另外请注意,这些进程具有PPID=28822
,而不是1
。
另外,请注意multiprocessing doc says following:
此外,它们不是Unix守护程序或服务,它们是正常进程,如果非守护进程退出,它们将终止(而不加入)。
但是,当我使用os.fork()
1,2 和handle singnal.SIGCHLD
进行两次分叉时,它不会留下无效的进程并正确分配PPID这些守护进程中的1个。例如,遵循ps
命令的输出:
$ ps axo pid,ppid,pgid,sess,comm --forest | grep -E 'python| PID'
PID PPID PGID SESS COMMAND
43680 43300 43680 43300 | \_ python3
43683 1 43682 43682 python3
$ ps axo pid,ppid,pgid,sess,comm --forest | grep -E 'python| PID'
PID PPID PGID SESS COMMAND
43680 43300 43680 43300 | \_ python3
43683 1 43682 43682 python3
43690 1 43689 43689 python3
$ ps axo pid,ppid,pgid,sess,comm --forest | grep -E 'python| PID'
PID PPID PGID SESS COMMAND
43680 43300 43680 43300 | \_ python3
43683 1 43682 43682 python3
43690 1 43689 43689 python3
43699 1 43698 43698 python3
$ ps axo pid,ppid,pgid,sess,comm --forest | grep -E 'python| PID'
PID PPID PGID SESS COMMAND
43680 43300 43680 43300 | \_ python3
43690 1 43689 43689 python3
43699 1 43698 43698 python3
$ ps axo pid,ppid,pgid,sess,comm --forest | grep -E 'python| PID'
PID PPID PGID SESS COMMAND
43680 43300 43680 43300 | \_ python3
43699 1 43698 43698 python3
$ ps axo pid,ppid,pgid,sess,comm --forest | grep -E 'python| PID'
PID PPID PGID SESS COMMAND
43680 43300 43680 43300 | \_ python3
请注意,使用pid 43680的进程是服务器。 pid为{43683,43690,43699}的进程是守护程序。它们已创建并正常退出,而不会保留为<defunct>
。另外请注意,这些进程具有PPID=1
。
在我的情况下,我应该选择哪种方法?
更新
我试图了解在哪种情况/需求下使用哪种方法。
考虑一下,稍有不同的要求:如果我想让服务器预先创建守护进程(从某些配置中读取它们的计数),然后让服务器简单地将不同的传入请求分配给当前空闲的其他守护程序(或将这些请求放入守护程序的队列),该怎么办?在这种情况下,设置守护进程(使用os.fork
进行两次分叉创建)有意义吗?
在最初的需求/场景中,跟随使用multiprocessing.Process()
创建的工作人员有意义吗?