在Python中处理SIGTERM时阻塞SIGUSR1(sigaction(2)的sa_掩码)

在Python中处理SIGTERM时阻塞SIGUSR1(sigaction(2)的sa_掩码),python,signals,Python,Signals,sigaction(2)调用有一个mask参数,允许在处理信号时阻止其他不同类型的信号 在处理SIGTERM时,我希望SIGUSR1被阻止。Python信号模块似乎没有sigaction调用,只有一个函数来阻止信号(这将导致竞争条件)。如何为处理程序设置此块掩码?Python信号处理程序不会在低级(C)信号处理程序中执行。相反,低级信号处理程序设置一个标志,告诉虚拟机在稍后的时间点(例如在下一个字节码指令)执行相应的Python信号处理程序 因此,尝试阻止是没有意义的。虽然它有点让它被封锁了:

sigaction(2)调用有一个mask参数,允许在处理信号时阻止其他不同类型的信号


在处理SIGTERM时,我希望SIGUSR1被阻止。Python信号模块似乎没有sigaction调用,只有一个函数来阻止信号(这将导致竞争条件)。如何为处理程序设置此块掩码?

Python信号处理程序不会在低级(C)信号处理程序中执行。相反,低级信号处理程序设置一个标志,告诉虚拟机在稍后的时间点(例如在下一个字节码指令)执行相应的Python信号处理程序

因此,尝试阻止是没有意义的。虽然它有点让它被封锁了:

from ctypes import Structure, POINTER, CFUNCTYPE, CDLL, byref, get_errno, \
    sizeof, c_int, c_long, c_ulong, c_void_p
from ctypes.util import find_library
from typing import Callable


class SIGSET_T(Structure):
    _fields_ = [
        ("__val", c_ulong * (1024 // (8 * sizeof(c_long)))),
    ]

SA_HANDLER_FUNCTYPE = CFUNCTYPE(None, c_int, use_errno=True)

class SIGACTION(Structure):
    _fields_ = [
        ("sa_handler", SA_HANDLER_FUNCTYPE),
        ("sa_mask", SIGSET_T),
        ("sa_flags", c_int),
        ("sa_restorer", c_void_p),
    ]


libc = CDLL(find_library('c'), use_errno=True)


def sigaction(signal, sighandler: Callable[[int], None], masked_signals=None):
    """Change the action taken by a process on receipt
    of a specific signal.

    A partial Python wrapper for the sigaction(2) function.

    :param signal: a signal value (from the signal module)
    :param sighandler: handler to install
    :param masked_signals: list of other signals to block while handling

    :raises: OSError if a library call fails
    """
    action = SIGACTION(sa_handler=SA_HANDLER_FUNCTYPE(sighandler))

    for maksed_signal in (masked_signals or []):
        if libc.sigaddset(byref(action.sa_mask), maksed_signal.value) != 0:
            if get_errno() != 0:
                raise OSError(get_errno())

    if libc.sigaction(signal.value, byref(action), None) != 0:
        if get_errno() != 0:
            raise OSError(get_errno())