子进程即使使用nohup也被杀死了

8
我正在使用subprocess.Popen启动多个进程。
代码如下:
while flag > 0:
   flag = check_flag()
   c = MyClass(num_process=10)
   c.launch()

MyClass 是类似下面这样的东西:

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)

在大多数情况下,启动的子进程会死亡,有时是在运行中途。 在某些情况下,它会完成。

但是,如果我直接在while循环中使用subprocess.Popen,该进程将继续并及时完成。

有人能告诉我如何通过上述方式使用subprocess使进程在后台运行吗?


1
(我不确定这是否重要),尝试保留对进程的引用,以避免它们被垃圾回收,另外,您确定脚本没有正常终止吗? - Pedru
3
使用子进程来调用另一个Python脚本有些奇怪。那个脚本做了什么,你不能直接导入并调用它吗?multiprocessing模块可以帮助您并行运行该脚本的代码。 - bbayles
另一个脚本运行时间很长,因此需要使用子进程。 - Abhishek Thakur
@Pedru 是的,脚本没有正常终止。我正在追踪它。另外,正如我所提到的,当直接使用子进程从while循环中调用相同的脚本时,它可以工作! - Abhishek Thakur
1- Popen()单独启动进程“在后台”(https://dev59.com/M1oU5IYBdhLWcg3w1pX2#37059478) 2- “子进程被杀死”是什么意思?你怎么知道?ps输出?你在bash中按下Ctrl+C吗?你退出shell(Ctrl+D)吗?你看到任何错误吗?你尝试生成唯一的日志文件名或使用追加模式:open('logfile.log', 'ab', 0)? 3- 无关:使用close_fds=True - jfs
1个回答

8

nohup只有在您的主进程正常退出时停止SIGHUP信号。对于其他信号,如SIGINT或SIGTERM,子进程会接收与父进程相同的信号,因为它们在同一进程组中。使用Popen的参数有两种方法。

设置子进程组:

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

使子进程忽略这些信号:

更多信息请查看另一篇文章

def preexec_function():
    signal.signal(signal.SIGINT, signal.SIG_IGN)
subprocess.Popen( ... , preexec_fn=preexec_function)

1
实际上,我无法在我的CentOS7机器上使用Python2.7重现您的问题。您的问题似乎是特定于平台的。如果上述解决方案不起作用,请提供更多有关子进程的调试信息(使用gdb查看导致它们中止的信号)。 - gdlmx
我使用的是Ubuntu 14.04。我会检查GDB。 - Abhishek Thakur
最终,我成功地在Raspbian RPi上将ngrok启动在后台,并且在Python脚本完成后未被杀掉。谢谢。 - IlirB

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接