8

I'm using subprocess.Popen to launch several processes.

The code is something like this:

while flag > 0:
   flag = check_flag()
   c = MyClass(num_process=10)
   c.launch()

MyClass if something like the following:

MyClass(object)
   def __init__(self, num_process):
      self.num_process = num_process

   def launch(self):
      if self.check_something() < 10:
         for i in range(self.num_process):
             self.launch_subprocess()

   def launch_subprocess(self):
      subprocess.Popen(["nohup",
                       "python",
                       "/home/mypythonfile.py"],
                       stdout=open('/dev/null', 'w'),
                       stderr=open('logfile.log', 'w'),
                       shell=False)

In most of the cases, the launched subprocess dies, sometimes in the middle of the run. In some cases, it completes.

However, if I use subprocess.Popen directly in the while loop, the process continues and finished timely.

Could someone tell me how can I get the processes to run in the background by using subprocess in the way as I described above?

Abhishek Thakur
  • 16,337
  • 15
  • 66
  • 97
  • 1
    (I'm not sure this matters), try to keep a reference to the processes to avoid them being garbage collected, and also, are you sure the scripts do not terminate normally? – Pedru May 09 '16 at 15:07
  • 3
    It's a bit odd to use a subprocess to call another Python script. What's that script doing that you can't import and call directly? The `multiprocessing` module may help you run that script's code in parallel. – bbayles May 09 '16 at 15:08
  • The other script takes a long time to run thats why subprocess – Abhishek Thakur May 09 '16 at 15:09
  • @Pedru yeah. the scripts dont terminate normally. I'm tracking it. Also, as I mentioned, the same script when called from the while loop directly using subprocess, works! – Abhishek Thakur May 09 '16 at 15:35
  • 1- [`Popen()` alone starts processes "in the background"](http://stackoverflow.com/a/37059478/4279) 2- What does it mean *"subprocess gets killed"* How do you know? `ps` output? Do you press `Ctrl+C` in the bash? Do you exit the shell (`Ctrl+D`). Do you see any errors? Have you tried to generate a unique logfile name or use the append mode: `open('logfile.log', 'ab', 0)`? 3- unrelated: use `close_fds=True`. – jfs May 10 '16 at 18:30

1 Answers1

8

The nohup only stop the SIGHUP signal when your master process exits normally. For other signal like SIGINT or SIGTERM, the child process receives the same signal as your parent process because it's in the same process group. There're two methods using the Popen's preexec_fn argument.

Setting the child process group:

subprocess.Popen(['nohup', 'python', '/home/mypythonfile.py'],
                 stdout=open('/dev/null', 'w'),
                 stderr=open('logfile.log', 'a'),
                 preexec_fn=os.setpgrp )

More information goes in another post.

Making the subprocesses ignore those signals:

def preexec_function():
    signal.signal(signal.SIGINT, signal.SIG_IGN)
subprocess.Popen( ... , preexec_fn=preexec_function)
Community
  • 1
  • 1
gdlmx
  • 6,479
  • 1
  • 21
  • 39
  • 1
    Actually I cannot reproduce your problem in my CentOS7 machine with Python2.7. Your problem seems to be platform specific. If the solutions above don't work, pls provide more debug info of your subprocesses (using `gdb` to see what signal causes their abortion). – gdlmx May 09 '16 at 16:32
  • I'm on ubuntu 14.04. I'll check gdb – Abhishek Thakur May 09 '16 at 17:02
  • Finally I was able to launch ngrok in background on Raspbian RPi and not get it killed when python script finished. Thanks. – IlirB Oct 30 '17 at 20:30