Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 当线程死亡时,子进程死亡_Python_Python 3.x_Subprocess_Python Multithreading - Fatal编程技术网

Python 当线程死亡时,子进程死亡

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

我有一个程序可以触发Python定时器来生成子进程。一旦我的程序终止或终止,这些子进程就应该终止。为了做到这一点,我使用了“prctl hack”,它设置了孩子在父母去世后应该收到的信号。我得到的不受欢迎的行为是:即使我的主要进程正在运行,孩子们也会被杀。以下代码重新创建了该问题:

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)