Горе сигнала Python: обработчик SIGQUIT задерживает выполнение если SIGQUIT, полученный во время выполнения другого обработчика сигналов?

    var p =[{"username":"ordermanageadmin","user_id":"2","resource_id":"Magento_Sales::actions"},
{"username":"ordermanageadmin_1","user_id":"3","resource_id":"Magento_Sales::actions"}]
for(var value in p) {
    for (var key in value) {
        if (p.hasOwnProperty(key)) {
            console.log(key + " -> " + p[key]);
        }
    }
}
9
задан jophab 29 December 2016 в 16:40
поделиться

2 ответа

Ваша большая проблема блокируется в обработчиках сигналов.

Этому обычно препятствуют, так как это может привести к странным условиям синхронизации. Но это - не совсем причина Вашей проблемы начиная с условия синхронизации, для которого Вы уязвимы, существует из-за Вашего выбора обработчиков сигналов.

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

#!/usr/bin/python

from signal import *
from time import sleep
from sys import stdout

print_Qs = 0
print_Zs = 0

def write(text):
    stdout.write(text)
    stdout.flush()

def process_quit(signum, frame):
     global print_Qs
     print_Qs = 10

def process_tstp(signum, frame):
     global print_Zs
     print_Zs = 10

signal(SIGQUIT, process_quit)
signal(SIGTSTP, process_tstp)

while 1:
    if print_Zs:
        print_Zs -= 1
        c = 'Z'
    elif print_Qs:
        print_Qs -= 1
        c = 'Q'
    else:
        c = '.'
    write(c)
    sleep(0.5)

Так или иначе вот то, что продолжается.

SIGTSTP является более особенным, чем SIGQUIT.

SIGTSTP маскирует другие сигналы от того, чтобы быть поставленным, в то время как его обработчик сигналов работает. Когда ядро идет для поставки SIGQUIT и видит, что обработчик SIGTSTP все еще работает, это просто на потом сохраняет его. После того как другой сигнал проникает для доставки, такой как SIGINT, когда Вы, CTRL+C (иначе KeyboardInterrupt), ядро помнит, что никогда не поставляло SIGQUIT и поставляет его теперь.

Вы заметите, изменяетесь ли Вы while 1: кому: for i in range(60): в основном цикле и делают Ваш тестовый сценарий снова, программа выйдет, не выполняя обработчик SIGTSTP, так как выход не повторно инициировал механизм доставки сигнала ядра.

Удачи!

6
ответ дан 4 December 2019 в 23:08
поделиться

На Python 2.5.2 на Linux 2.6.24, Ваш код работает точно, поскольку Вы описываете свои желаемые результаты (если сигнал получен, все еще обрабатывая предыдущий сигнал, новый сигнал сразу обрабатывается после того, как первый закончен).

На Python 2.4.4 на Linux 2.6.16, я вижу проблемное поведение, которое Вы описываете.

Я не знаю, является ли это из-за изменения в Python или в ядре Linux.

1
ответ дан 4 December 2019 в 23:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: