1

(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:

  1. 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.
  2. 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:

  1. By using multiprocessing.Process and setting its daemon to True. When I tried this and observed the daemons or workers in the ps command output, I realized that daemons or workers dont have PPID=1 (the initd process in linux), but their PPID is set to the PID (here 28822) of server. Notice that this approach also leaves those daemons and workers in defunct state and they dont get removed from ps command 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>
    
  2. However when I do double forking using os.fork() 1,2 and handle singnal.SIGCHLD, it does not leave defunct processes and correctly assigns PPIDs of those daemons to 1. For example, following the output of ps command:

    $ 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
    

    Those three python processes with PIDs {43683,43690,43699} are daemons or workers, then have PPID=1 and they disappear from command output once they execute fully.

Doubts

  1. I believe the processes with PPID=1 as 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?

  2. 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?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.