CodeWalk

Python信号处理:signal模块与异步信号

作者:我还是少年 · 2026-05-30 12:55

请介绍Python signal模块的用途、基本用法(注册信号处理器)、可捕获的信号列表(SIGINT/SIGTERM/SIGUSR1等)、限制(信号只能在主线程注册),以及Python中异步信号处理的局限性。

回答

我还是少年

signal模块基本用法

import signal
import time

def handler(signum, frame):
    print(f'收到信号 {signum}')

# 注册信号处理器
signal.signal(signal.SIGINT, handler)  # Ctrl+C
signal.signal(signal.SIGTERM, handler)  # kill命令

print('等待信号...')
while True:
    time.sleep(1)

常用信号

信号默认动作触发方式
SIGINT终止进程Ctrl+C
SIGTERM终止进程kill <pid>
SIGUSR1终止进程用户自定义
SIGUSR2终止进程用户自定义
SIGHUP终止进程终端断开
SIGCHLD忽略子进程状态变化
SIGALRM终止进程alarm()定时器

关键限制

  1. 主线程限制signal.signal()只能在主线程注册
  2. 中断处理:信号处理函数执行期间,该信号被屏蔽
  3. 与asyncio不兼容:asyncio默认不处理信号,需使用loop.add_signal_handler()
  4. Windows限制:仅支持SIGINTSIGTERMSIGBREAK

定时器信号

import signal

def timeout_handler(signum, frame):
    raise TimeoutError('操作超时')

# 设置5秒超时
signal.signal(signal.SIGALRM, timeout_handler)
signal.alarm(5)

try:
    long_running_operation()
except TimeoutError:
    print('超时!')
finally:
    signal.alarm(0)  # 取消定时器

优雅关闭模式

import signal

running = True

def shutdown(signum, frame):
    global running
    print('正在优雅关闭...')
    running = False

signal.signal(signal.SIGINT, shutdown)
signal.signal(signal.SIGTERM, shutdown)

while running:
    do_work()