Обработчик python SIGTEM не вызывается в многопроцессорной среде - PullRequest
0 голосов
/ 19 декабря 2018

Я воспроизвел следующий фрагмент кода, чтобы воспроизвести проблему, с которой я столкнулся при работе с обработчиком 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 голосов
/ 20 декабря 2018

Python 2 страдает от нескольких проблем, когда речь идет о микшировании потоков и сигналов, и это обычно не рекомендуется.Вы можете прочитать некоторую информацию относительно официальной документации .

Более подробно, что вас поражает, так это то, что в Python 2 несколько примитивов, использующих базовые блокировки, не могут прерываться сигналами. проблема .

Эта проблема больше не затрагивает Python 3, поэтому я настоятельно рекомендую вам перейти на более новую версию интерпретатора.

Если вы не можете поступить иначеОбходной путь должен установить тайм-ауты для блокирующих операций, таких как Queue.get.

...