Python 当线程死亡时,子进程死亡
我有一个程序可以触发Python定时器来生成子进程。一旦我的程序终止或终止,这些子进程就应该终止。为了做到这一点,我使用了“prctl hack”,它设置了孩子在父母去世后应该收到的信号。我得到的不受欢迎的行为是:即使我的主要进程正在运行,孩子们也会被杀。以下代码重新创建了该问题:Python 当线程死亡时,子进程死亡,python,python-3.x,subprocess,python-multithreading,Python,Python 3.x,Subprocess,Python Multithreading,我有一个程序可以触发Python定时器来生成子进程。一旦我的程序终止或终止,这些子进程就应该终止。为了做到这一点,我使用了“prctl hack”,它设置了孩子在父母去世后应该收到的信号。我得到的不受欢迎的行为是:即使我的主要进程正在运行,孩子们也会被杀。以下代码重新创建了该问题: from threading import Timer import time import os import subprocess import ctypes import signal def set_pde
from threading import Timer
import time
import os
import subprocess
import ctypes
import signal
def set_pdeathsig():
print("child PID: %d" % os.getpid())
print("child's parent PID: %d" % os.getppid())
prctl = ctypes.CDLL("libc.so.6").prctl
PR_SET_PDEATHSIG = 1
prctl(PR_SET_PDEATHSIG, signal.SIGTERM)
def thread1():
subprocess.Popen(['sleep', 'infinity'], preexec_fn=set_pdeathsig)
time.sleep(10)
print("thread 1 finished")
def thread2():
subprocess.Popen(['sleep', 'infinity'], preexec_fn=set_pdeathsig)
time.sleep(10)
print("thread 2 finished")
print("main thread PID: %d" % os.getpid())
t1 = Timer(1, thread1)
t2 = Timer(1, thread2)
t1.start()
t2.start()
time.sleep(100)
您可以注意到,在线程死亡之前,
sleep
进程仍在运行。计时器线程死亡后,其相应的子进程也会死亡,即使主线程处于活动状态。这是预期的,甚至是记录在案的行为。从prctl(2)的手册页:
这意味着您需要在其他地方生成子流程。如果您在退出的线程中执行此操作,那么您的子进程将按预期方式终止,并且没有办法解决此问题
我将添加另一个线程并从那里启动进程。你喜欢这项工作吗
from threading import Timer
from threading import Thread
import queue
import time
import os
import subprocess
import ctypes
import signal
def set_pdeathsig():
print("child PID: %d" % os.getpid())
print("child's parent PID: %d" % os.getppid())
prctl = ctypes.CDLL("libc.so.6").prctl
PR_SET_PDEATHSIG = 1
prctl(PR_SET_PDEATHSIG, signal.SIGTERM)
def thread1(q):
q.put(["sleep", "infinity"])
time.sleep(5)
print("thread 1 finished")
def thread2(q):
q.put(["sleep", "infinity"])
time.sleep(5)
print("thread 2 finished")
def process_manager(q):
while True:
foo = q.get()
subprocess.Popen(foo, preexec_fn=set_pdeathsig)
print("main thread PID: %d" % os.getpid())
qu = queue.Queue()
pm_thread = Thread(group=None, target=process_manager, args=(qu,))
pm_thread.daemon = True
pm_thread.start()
t1 = Timer(1, thread1, args=(qu,))
t2 = Timer(1, thread2, args=(qu,))
t1.start()
t2.start()
time.sleep(15)
这就是您希望它做的(用于测试的Python3.5)。当然,可能有一些原因导致编排线程不适合,但我还是将其作为备选解决方案提供。现在,您的子进程在计时器线程死亡后仍然存在,但在主线程退出时仍将终止 显然,您没有调用函数
os.setpgid
Thank@TheophileDano,这只是以前测试中的代码。那不应该在那里。如果将其删除,问题仍然存在。
from threading import Timer
from threading import Thread
import queue
import time
import os
import subprocess
import ctypes
import signal
def set_pdeathsig():
print("child PID: %d" % os.getpid())
print("child's parent PID: %d" % os.getppid())
prctl = ctypes.CDLL("libc.so.6").prctl
PR_SET_PDEATHSIG = 1
prctl(PR_SET_PDEATHSIG, signal.SIGTERM)
def thread1(q):
q.put(["sleep", "infinity"])
time.sleep(5)
print("thread 1 finished")
def thread2(q):
q.put(["sleep", "infinity"])
time.sleep(5)
print("thread 2 finished")
def process_manager(q):
while True:
foo = q.get()
subprocess.Popen(foo, preexec_fn=set_pdeathsig)
print("main thread PID: %d" % os.getpid())
qu = queue.Queue()
pm_thread = Thread(group=None, target=process_manager, args=(qu,))
pm_thread.daemon = True
pm_thread.start()
t1 = Timer(1, thread1, args=(qu,))
t2 = Timer(1, thread2, args=(qu,))
t1.start()
t2.start()
time.sleep(15)