KiY*_*ter 5 python linux ubuntu ctypes signals
我已经尝试使用 sigaction 和 ctypes 设置信号处理程序。(我知道它可以在 python 中使用信号模块,但我想尝试学习。)
当我将 SIGTERM 发送到这个进程,但它没有调用我设置的处理程序时,只打印“终止”。为什么它不调用处理程序?
我使用 Ubuntu 19.10 和 Python 3.7.5 x64。
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
Run Code Online (Sandbox Code Playgroud)
清单[Python 3.Docs]:ctypes - Python 的外部函数库。
代码存在一些问题:
struct sigaction *
(指针)作为参数传递给sigaction代码00.py:
#!/usr/bin/env python3
import sys
import os
import time
from ctypes import Structure, Union, POINTER, CFUNCTYPE, CDLL, byref, sizeof, \
c_short, c_int, c_uint, c_long, c_ulong, c_char_p, c_void_p
SIGTERM = 15
class sigset_t(Structure):
_fields_ = [
("__val", c_ulong * (1024 // (8 * sizeof (c_long)))),
]
'''
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),
("_pad", c_int * 29),
]
sa_sigaction_functype = CFUNCTYPE(None, c_int, POINTER(siginfo_t), c_void_p)
'''
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(None)
def sighandler(sig): # Signal handler function
libc.puts.argtypes = [c_char_p]
libc.puts.restype = c_int
libc.puts("Custom signal handler called for signal {0:d}".format(sig).encode())
def main(*argv):
libc.sigaction.argtypes = [c_int, POINTER(SIGACTION), POINTER(SIGACTION)]
libc.sigaction.restype = c_int
signal_number = SIGTERM
act = SIGACTION(sa_handler=sa_handler_functype(sighandler))
#print(act)
res = libc.sigaction(signal_number, byref(act), None)
print("sigaction result: {0:d}".format(res))
print("PId {0:d} waiting for SIG {1:d}...".format(os.getpid(), signal_number))
while 1:
time.sleep(0.1)
if __name__ == "__main__":
print("Python {0:s} {1:d}bit on {2:s}\n".format(" ".join(item.strip() for item in sys.version.split("\n")), 64 if sys.maxsize > 0x100000000 else 32, sys.platform))
main(*sys.argv[1:])
print("\nDone.")
Run Code Online (Sandbox Code Playgroud)
输出(程序运行时,从另一个终端发送SIGTERM两次,然后发送SIGKILL):
Run Code Online (Sandbox Code Playgroud)[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q059521251]> uname -m x86_64 [cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q059521251]> cat /etc/lsb-release | grep DESCR DISTRIB_DESCRIPTION="Ubuntu 16.04.6 LTS" [cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q059521251]> python3 code00.py Python 3.5.2 (default, Oct 8 2019, 13:06:37) [GCC 5.4.0 20160609] 64bit on linux sigaction result: 0 PId 20050 waiting for SIG 15... Custom signal handler called for signal 15 Custom signal handler called for signal 15 Killed
归档时间: |
|
查看次数: |
248 次 |
最近记录: |