0

I have written a server which accepts a requests on certain port and forks a new daemon to handle each of those requests. I am doing forking with multiprocessing module. The basic code (with no port listening logic, as its not my doubt here) looks like this:

Code (mu_min.py)

import time
import multiprocessing as mup
import sys
import os

def worker(name):
    a = 0

    while(a < 5):
        print(name,":",a)
        a = a+1
        time.sleep(2)
        pass 

    print("Exiting worker: ", name, "(", os.getpid(), ")")

def start_server():
    b = 0

    while(b<3):
        new_worker = mup.Process(target=worker,args=('worker-'+str(b),))
        new_worker.daemon = True
        new_worker.start()
        b = b + 1
        time.sleep(3)

    time.sleep(3600)

start_server()

The output

worker-0 : 0
worker-0 : 1
worker-0 : 2
worker-0 : 3
worker-0 : 4
Exiting worker:  worker-0 ( 32831 )
worker-1 : 0
worker-1 : 1
worker-1 : 2
worker-1 : 3
worker-1 : 4
Exiting worker:  worker-1 ( 32834 )
worker-2 : 0
worker-2 : 1
worker-2 : 2
worker-2 : 3
worker-2 : 4
Exiting worker:  worker-2 ( 32837 )

ps command output

If I continuously run ps command in other terminal, I get following output:

[user@machine mu_min]$ ps axo pid,ppid,pgid,sess,comm --forest | grep -E 'python| PID'
   PID   PPID   PGID   SESS COMMAND
[user@machine mu_min]$ python3 mu_min.py > mu_min_nix_out &
[1] 32830
[user@machine mu_min]$ ps axo pid,ppid,pgid,sess,comm --forest | grep -E 'python| PID'
   PID   PPID   PGID   SESS COMMAND
 32830  25898  32830  25898  |           \_ python3
 32831  32830  32830  25898  |           |   \_ python3
[user@machine mu_min]$ ps axo pid,ppid,pgid,sess,comm --forest | grep -E 'python| PID'
   PID   PPID   PGID   SESS COMMAND
 32830  25898  32830  25898  |           \_ python3
 32831  32830  32830  25898  |           |   \_ python3
 32834  32830  32830  25898  |           |   \_ python3
[user@machine mu_min]$ ps axo pid,ppid,pgid,sess,comm --forest | grep -E 'python| PID'
   PID   PPID   PGID   SESS COMMAND
 32830  25898  32830  25898  |           \_ python3
 32831  32830  32830  25898  |           |   \_ python3
 32834  32830  32830  25898  |           |   \_ python3
 32837  32830  32830  25898  |           |   \_ python3
[user@machine mu_min]$ ps axo pid,ppid,pgid,sess,comm --forest | grep -E 'python| PID'
   PID   PPID   PGID   SESS COMMAND
 32830  25898  32830  25898  |           \_ python3
 32831  32830  32830  25898  |           |   \_ python3 <defunct>
 32834  32830  32830  25898  |           |   \_ python3
 32837  32830  32830  25898  |           |   \_ python3
[user@machine mu_min]$ ps axo pid,ppid,pgid,sess,comm --forest | grep -E 'python| PID'
   PID   PPID   PGID   SESS COMMAND
 32830  25898  32830  25898  |           \_ python3
 32831  32830  32830  25898  |           |   \_ python3 <defunct>
 32834  32830  32830  25898  |           |   \_ python3 <defunct>
 32837  32830  32830  25898  |           |   \_ python3
[user@machine mu_min]$ ps axo pid,ppid,pgid,sess,comm --forest | grep -E 'python| PID'
   PID   PPID   PGID   SESS COMMAND
 32830  25898  32830  25898  |           \_ python3
 32831  32830  32830  25898  |           |   \_ python3 <defunct>
 32834  32830  32830  25898  |           |   \_ python3 <defunct>
 32837  32830  32830  25898  |           |   \_ python3 <defunct>

I have following doubts

  1. multiprocessing doc page 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 isn't multiprocessing creating real daemons (as explained in below doubt)? Also I dont get meaning of "that will be terminated (and not joined) if non-daemonic processes have exited." What does it mean?

  2. I prepared similar code with double forking using os.fork() handling signal.SIGCHLD. Handling signal.SIGCHLD seems to not leave back defunct processes. Also, it seems that, due to double forking, any processes created were created with PPID=1, making them proper daemons. Notice that in above ps command output PPID of defunct processes is not 1. So they seem not to be proper daemons. Is it so?

Mahesha999
  • 22,693
  • 29
  • 116
  • 189

1 Answers1

0

Answering your first question:

These processes aren't real Unix daemons, they're "daemon" in the same sense as daemon threads within a process.

If your main process finishes and a secondary non-daemon process is still running, the main process will "join" it, i.e. wait for it to finish before exiting. If the secondary process is a daemon, however, it will be terminated when the main process finishes.

Mikhail Burshteyn
  • 4,762
  • 14
  • 27