python SIGTEM处理程序未在多处理中调用

时间:2018-12-19 13:33:19

标签: python-2.7 multiprocessing signals signal-processing sigterm

我复制了以下代码片段,以重现我在处理SIGTERM处理程序时遇到的问题-

  1. 具有SIGTERM处理程序的主进程。

  2. 从主进程产生的线程

  3. 从上述线程产生的子进程

目的是要了解SIGTERM处理程序的工作原理。我假设SIGTERM处理程序将由生成的线程以及进程继承。有一个部分发生死锁(因为未读取共享队列)。由于存在死锁,因此可以使所有进程和线程保持活动状态。

from multiprocessing import Process, Queue
from threading import Thread
import os
import sys
import signal


def sigtermHandlerNew():
    print "SIGTERM received for process: {}".format(os.getpid())
    sys.exit()


def f(q):
    print "f proc id: {}".format(os.getpid())
    q.put('X' * 1000000)


def proc_starter():
    queue = Queue()
    p = Process(target=f, args=(queue,))
    p.start()
    p.join()  # this deadlocks
    obj = queue.get()


def main():
    signal.signal(signal.SIGTERM, sigtermHandlerNew)
    print "main process id: {}".format(os.getpid())
    t = Thread(target=proc_starter)
    t.start()
    t.join()


main()

运行此程序后,将运行2个进程。我在这里观察到一个奇怪的行为-当我尝试使用SIGTERM($ kill -15 <proc-id>)杀死任何进程时,我发现SIGTERM处理程序的功能没有被调用,并且这个死锁一直存在(直到我通知SIGKILL)

有人可以帮助我理解为什么流程未兑现信号的原因。您可以直接运行此代码段。

1 个答案:

答案 0 :(得分:1)

Python 2在混合线程和信号时遇到许多问题,通常不建议这样做。您可以在官方documentation中阅读有关此方面的信息。

更深入地讲,影响您的是,在Python 2中,使用基本锁的多个原语不能被信号issue中断。

此问题不再影响Python 3,因此我强烈建议您切换到较新版本的解释器。

如果您不能这样做,一种解决方法是将超时设置为阻止操作,例如Queue.get