尽管我在PythoncTypes中设置了信号处理程序,但它不会被调用

尽管我在PythoncTypes中设置了信号处理程序,但它不会被调用,python,linux,ubuntu,signals,ctypes,Python,Linux,Ubuntu,Signals,Ctypes,我尝试过用sigaction和ctypes设置信号处理程序。(我知道它可以在python中使用信号模块,但我想尝试一下以了解。) 当我将SIGTERM发送到此进程,但它不调用我设置的处理程序时,只打印“已终止”。 为什么它不调用处理程序 我正在使用Ubuntu19.10和Python3.7.5x64 import ctypes from ctypes import * from ctypes.util import * from os import getpid class sigset_t

我尝试过用sigaction和ctypes设置信号处理程序。(我知道它可以在python中使用信号模块,但我想尝试一下以了解。)

当我将SIGTERM发送到此进程,但它不调用我设置的处理程序时,只打印“已终止”。 为什么它不调用处理程序

我正在使用Ubuntu19.10和Python3.7.5x64

import ctypes
from ctypes import *
from ctypes.util import *
from os import getpid


class sigset_t(Structure):
    __fields__ = [
        ("__val",               c_ulong*16)        
    ]

class sigval_t(Union):
    __fields__ = [
        ("sival_int",           c_int),
        ("sival_ptr",           c_void_p)
    ]



class siginfo_t(Structure):
    __fields__ = [
        ("si_signo",            c_int),
        ("si_errno",            c_int),
        ("si_code",             c_int),
        ("si_trapno",           c_int),
        ("si_pid",              c_uint),
        ("si_status",           c_int),
        ("si_utime",            c_long),
        ("si_stime",            c_long),
        ("si_value",            sigval_t),
        ("si_int",              c_int),
        ("si_ptr",              c_void_p),
        ("si_overrun",          c_int),
        ("si_timerid",          c_int),
        ("si_addr",             c_void_p),
        ("si_band",             c_long),
        ("si_fd",               c_int),
        ("si_addr_lsb",         c_short),
        ("si_call_addr",        c_void_p),
        ("si_syscall",          c_int),
        ("si_arch",             c_uint)

    ]

sa_handler_functype = CFUNCTYPE(None, c_int)
sigaction_functype = CFUNCTYPE(None, c_int, siginfo_t, c_void_p)


class SIGACTION(Structure):
    __fields__ = [
        ("sa_handler",          sa_handler_functype),
        ("sa_sigaction",        sigaction_functype),
        ("sa_mask",             sigset_t),
        ("sa_flags",            c_int),

    ]


def p(sig): # signal handler function
    libc.puts("bye")

libc_path = find_library("c")
libc = CDLL(libc_path)

libc.sigaction.restype = c_int
libc.sigaction.argtypes = [c_int, POINTER(SIGACTION), POINTER(SIGACTION)]

act = SIGACTION(sa_handler=sa_handler_functype(p))
print(act)
res = libc.sigaction(15, act, None)
print(res)
print("pid:", getpid()) # show pid
while True: # wait until receive sigterm signal
    pass
上市

代码存在一些问题:

  • ctypes.Structure子体需要定义\u字段而不是\u字段)。相应地改变了结构
  • struct sigaction*
    (指针)作为参数传递给sigaction
  • 基于/usr/include/bits中文件的内容修改了结构定义(在我的Ubtu 16 x64虚拟机上)
  • 为任何使用过的函数(puts)定义了argtypes和restype。查看更多详细信息
  • 其他(轻微)变化
代码00.py:

#/usr/bin/env蟒蛇3
导入系统
导入操作系统
导入时间
从ctypes导入结构、联合、指针、CFUNCTYPE、CDLL、byref、sizeof、\
c_short,c_int,c_uint,c_long,c_ulong,c_char_p,c_void_p
SIGTERM=15
类信号集(结构):
_字段=[
("c_val),c_ulong*(1024/)(8*sizeof(c_long)),,
]
'''
类符号(联合):
_字段=[
(“西瓦里特”,西瓦里特),
(“sival_ptr”,c_void_p),
]
类别信息(结构):
_字段=[
(“siu signo”,c_int),
(“si_errno”,c_int),
(“si_代码”,c_int),
(“_pad”,c_int*29),
]
sa_sigaction_functype=CFUNCTYPE(无,c_int,指针(siginfo_t),c_void_p)
'''
sa_handler_functype=CFUNCTYPE(无,c_int,use_errno=True)
集体诉讼(结构):
_字段=[
(“sa_handler”,sa_handler_functype),
(“sa_mask”,sigset_t),
(“萨乌旗”,c_int),
(“sa_restorer”,c_void_p),
]
libc=CDLL(无)
def信号处理器(sig):#信号处理器功能
libc.puts.argtypes=[c\u char\u p]
libc.puts.restype=c_int
puts(“为信号{0:d}调用的自定义信号处理程序”。格式(sig.encode())
def主(*argv):
libc.sigaction.argtypes=[c_int,指针(sigaction),指针(sigaction)]
libc.sigaction.restype=c_int
信号号=SIGTERM
act=SIGACTION(sa_handler=sa_handler_functype(signandler))
#印刷品(法案)
res=libc.sigaction(信号号,byref(act),无)
打印(“sigaction结果:{0:d}”。格式(res))
打印(“PId{0:d}正在等待SIG{1:d}…”。格式(os.getpid(),信号号))
而1:
睡眠时间(0.1)
如果名称=“\uuuuu main\uuuuuuuu”:
打印(“Python{0:s}{1:d}位在{2:s}\n.format(“.join(sys.version.split(“\n”)中的项的item.strip()),如果sys.maxsize>0x100000000,则为64,否则为32,sys.platform))
main(*sys.argv[1:])
打印(“\n完成”)
输出(程序运行时,从另一个终端发送两次SIGTERM,然后发送SIGKILL):

[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q059521251]>uname-m
x86_64
[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q059521251]>cat/etc/lsb发行版| grep DESCR
DISTRIB_DESCRIPTION=“Ubuntu 16.04.6 LTS”
[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q059521251]>python3 code00.py
Python 3.5.2(默认值,2019年10月8日13:06:37)[GCC 5.4.0 20160609]linux上64位
行动结果:0
PId 20050正在等待信号15。。。
为信号15调用自定义信号处理程序
为信号15调用自定义信号处理程序
被杀死的

我如何设置它?