Python模块之信号(signal)

在了解了Linux的信号基础之 后,Python标准库中的signal包就很容易学习和理解。signal包负责在Python程序内部处理信号,典型的操做包括预设信号处理函数,暂 停并等待信号,以及定时发出SIGALRM等。要注意,signal包主要是针对UNIX平台(好比Linux, MAC OS),而Windows内核中因为对信号机制的支持不充分,因此在Windows上的Python不能发挥信号系统的功能。html

  信号(signal)-- 进程之间通信的方式,是一种软件中断。一个进程一旦接收到信号就会打断原来的程序执行流程来处理信号。python

定义信号名

signal包定义了各个信号名及其对应的整数,好比:linux

import signal
print(signal.SIGABRT)
print(signal.SIG_DFL)

Python所用的信号名与Linux一致,能够经过$ man 7 signal 查询编程

预设信号处理函数

signal包的核心是使用signal.signal()函数来预设(register)信号处理函数,以下所示:windows

singnal.signal(signalnum, handler)app

signalnum为某个信号,handler为该信号的处理函数。咱们在信号基础里提到,进程能够无视信号,能够采起默认操做,还能够自定义操做。当handler为signal.SIG_IGN时,信号被无视(ignore)。当handler为singal.SIG_DFL,进程采起默认操做(default)。当handler为一个函数名时,进程采起函数中定义的操做。ide

参数 SIG_IGN SIG_DFL handler
解释 忽略 默认处理 类型的函数指针
实质 #define SIG_IGN ((sighandler_t)1) #define SIG_IGN ((sighandler_t)0) 执行本身写的代码
# Define signal handler function
def myHandler(signum, frame):
    print('I received: ', signum)

# register signal.SIGTSTP's handler
signal.signal(signal.SIGTSTP, myHandler)
#暂停进程,把当前进程置成就绪态,让出CPU,直到收到任意一个信号后终止,而且当处理完该信号以后,直接执行pause()函数下面的语句
signal.pause()

print('End of Signal Demo')
# 有问题待测试

  在主程序中,咱们首先使用signal.signal()函数来预设信号处理函数。而后咱们执行signal.pause()来让该进程暂停以等待信号, 以等待信号。当信号SIGUSR1被传递给该进程时,进程从暂停中恢复,并根据预设,执行SIGTSTP的信号处理函数myHandler()。 myHandler的两个参数一个用来识别信号(signum),另外一个用来得到信号发生时,进程栈的情况(stack frame)。这两个参数都是由signal.singnal()函数来传递的。函数

上面的程序能够保存在一个文件中(好比test.py)。咱们使用以下方法运行:学习

$python test.py测试

以便让进程运行。当程序运行到signal.pause()的时候,进程暂停并等待信号。此时,经过按下CTRL+Z向该进程发送SIGTSTP信号。咱们能够看到,进程执行了myHandle()函数, 随后返回主程序,继续执行。(固然,也能够用$ps查询process ID, 再使用$kill来发出信号。)

(进程并不必定要使用signal.pause()暂停以等待信号,它也能够在进行工做中接受信号,好比将上面的signal.pause()改成一个须要长时间工做的循环。)

咱们能够根据本身的须要更改myHandler()中的操做,以针对不一样的信号实现个性化的处理。

定时发出SIGALRM信号

一个有用的函数是signal.alarm(),它被用于在必定时间以后,向进程自身发送SIGALRM信号:

import signal
# Define signal handler function
def myHandler(signum, frame):
    print("Now, it's the time")
    exit()

# register signal.SIGALRM's handler 
signal.signal(signal.SIGALRM, myHandler)
signal.alarm(5)
while True:
    print('not yet')

  咱们这里用了一个无限循环以便让进程持续运行。在signal.alarm()执行5秒以后,进程将向本身发出SIGALRM信号,随后,信号处理函数myHandler开始执行。

发送信号

signal包的核心是设置信号处理函数。除了signal.alarm()向自身发送信号以外,并无其余发送信号的功能。但在os包中,有相似于linux的kill命令的函数,分别为

os.kill(pid, sid)

os.killpg(pgid, sid)

分别向进程和进程组(见Linux进程关系)发送信号。sid为信号所对应的整数或者singal.SIG*。

实际上signal, pause,kill和alarm都是Linux应用编程中常见的C库函数,在这里,咱们只不过是用Python语言来实现了一下。实际上,Python 的解释器是使用C语言来编写的,因此有此类似性也并不意外。此外,在Python 3.4中,signal包被加强,信号阻塞等功能被加入到该包中。咱们暂时不深刻到该包中。

总结

signal.SIG*

signal.signal()

signal.pause()  signal.pause阻塞函数,让进程暂停以等待信号,也就时阻塞进程执行,简单来讲当接收到信号后使进程中止。

signal.alarm()  经常使用做定时器,time为时间参数,单位为秒


  • SIGINT 表示终止进程

  • SIGQUIT 表示退出进程

  • SIGSTP 表示暂停进程

  • SIGKILL 表示结束某个进程,不能被忽略处理。

  • SIGALRM 表示时钟信号,经常使用做定时器,time为时间参数,单位为秒

  • SIGSTOP表示中止某个进程,且不能被忽略处理。

  • SIGCHLD表示子进程发送给父进程信号

  • SIGCONT 继续执行暂停的进程




SIGINT     终止进程     中断进程,不可经过signal.signal()捕捉(至关于Ctrl+C)

SIGTERM    终止进程     软件终止信号,可经过signal.signal()捕捉(默认信号,当os.kill()没有指明信号类型时,默认的是该信号)

SIGKILL    终止进程     杀死进程,不可捕捉(至关于linux下的kill命令,windows下使用会抛出异常)

SIGALRM    闹钟信号     能够经过signal.alarm()和os.kill()发送该信号,可经过signal.signal()捕捉


windows下只能使用这几个信号:

  • SIGABRT

  • SIGFPE

  • SIGILL

  • SIGINT

  • SIGSEGV

  • SIGTERM

相关文章
相关标签/搜索