(Note that, below, I am frequently using term "daemon or worker" just to indicate that I dont know which word to use as I dont know the exact difference between them in the context explained below.)
Consider following scenarios:
- I need to write a server listening on some port, which accepts a request on that port and fork a new daemon or worker for each of incoming requests to handle them.
- I need to write a server which starts some pre determined number of daemons or workers, then listens on some port, and finally it assigns incoming requests on that port to one of currently free daemons or workers. This approach pre-creates pre-determined number of daemons or workers just to avoid spawning huge numbers of them if I get huge number of requests, which might be the case in first scenario.
I am doing this in linux using python. I have came across two approaches to create daemon or worker:
By using
multiprocessing.Processand setting itsdaemontoTrue. When I tried this and observed the daemons or workers in thepscommand output, I realized that daemons or workers dont havePPID=1(theinitdprocess in linux), but theirPPIDis set to the PID (here28822) of server. Notice that this approach also leaves those daemons and workers in defunct state and they dont get removed frompscommand output automatically. I have to explicitly kill them.$ 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>However when I do double forking using
os.fork()1,2 and handlesingnal.SIGCHLD, it does not leave defunct processes and correctly assigns PPIDs of those daemons to 1. For example, following the output ofpscommand:$ 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 python3Those three python processes with PIDs {43683,43690,43699} are daemons or workers, then have
PPID=1and they disappear from command output once they execute fully.
Doubts
I believe the processes with
PPID=1as created by double forking are actual unix daemons. Also, notice the multiprocessing doc says following:Additionally, these are not Unix daemons or services, they are normal processes that will be terminated (and not joined) if non-daemonic processes have exited.
So, I feel the processes created by double forking are real linux daemons while the processes created by multiprocessing library are just workers, even though the library calls them daemons.
Am I right with this?
I want to know which approach will be suitable for above scenarios. I feel scenario 1 should be better implemented with multiprocessing approach, while scenario 2 should be better implemented with double forking approach.
Am I right with this?