Python signal模块包介绍和用法

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

 

定义信号名

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

import signal
print signal.SIGALRM
print signal.SIGCONT

Python所用的信号名和Linux一致。你可以通过

$man 7 signal

查询

 

预设信号处理函数

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

singnal.signal(signalnum, handler)

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

复制代码
import signal
# Define signal handler function
def myHandler(signum, frame):
    print('I received: ', signum)

# register signal.SIGTSTP's handler 
signal.signal(signal.SIGTSTP, myHandler)
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.alarm()

如果你喜欢这篇文章,欢迎推荐

### 回答1: signal模块提供了一种将信号发送到Python程序中的方法,它可以在外部事件发生时调用特定的函数。signal.signal函数接受两个参数:信号的数字标识符和要调用的函数。例如,要设置SIGINT(中断进程)信号,可以使用以下代码:signal.signal(signal.SIGINT, my_handler)。 ### 回答2: 在Python中,signal.signal()函数用于设置信号处理函数,即在程序中捕捉到特定信号时执行指定操作。这个函数的基本用法如下: 首先,需要导入signal模块: ```python import signal ``` 然后,我们可以定义一个函数来处理信号,这个函数通常需要带有两个参数(一个是信号编号,一个是当前调用的栈帧): ```python def signal_handler(signal, frame): # 执行特定操作 print('接收到信号') ``` 接下来,使用signal.signal()函数来设置信号处理函数: ```python signal.signal(signal.SIGUSR1, signal_handler) ``` 其中,signal.SIGUSR1是定义的一个信号常量,代表用户自定义的信号1,可以根据需要替换为其他信号常量。signal_handler是我们自定义的信号处理函数。 最后,可以通过发送信号来触发信号处理函数的执行: ```python import os os.kill(os.getpid(), signal.SIGUSR1) ``` 上述代码会向当前进程发送一个SIGUSR1信号,从而触发相应的信号处理函数的执行。在这个例子中,会打印出"接收到信号"的消息。 需要注意的是,Python的信号处理函数默认情况下只在主线程中执行。如果需要在子线程中处理信号,需设置线程信号函数的特殊标志: ```python signal.signal(signal.SIGUSR1, signal.SIG_IGN) # 忽略信号 signal.signal(signal.SIGUSR1, signal.SIG_DFL) # 使用默认处理函数 ``` 总之,signal.signal()函数能够让我们在Python中捕捉和处理各种信号,使得程序的执行更加灵活和可控。 ### 回答3: 在Python中,signal模块提供了signal.signal函数,用于设置信号处理程序。其用法如下: 首先,需要导入signal模块: import signal 然后,定义一个信号处理函数,该函数用于处理接收到的信号。函数的参数是信号编号以及当前堆栈的帧对象: def signal_handler(signal, frame): print('接收到信号') 接下来,使用signal.signal函数来设置信号处理程序。该函数有两个参数,第一个参数是要处理的信号编号,而第二个参数是信号处理函数: signal.signal(signal.SIGINT, signal_handler) 在这个例子中,我们将SIGINT信号(也就是Ctrl+C组合键)与signal_handler函数关联起来。当接收到SIGINT信号时,程序将调用signal_handler函数。 最后,我们可以通过调用signal.pause函数来使程序进入等待状态,等待信号的到来: signal.pause() 总结起来,使用signal.signal函数需要三个步骤:导入signal模块、定义信号处理函数、以及使用signal.signal函数设置信号处理程序。这样,程序就可以在接收到指定信号时调用特定的处理函数来进行相应的操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值