处理python中的信号
什么是信号
信号(signal)-- 进程间通讯的一种方式,也可作为一种软件中断的方法。一个进程一旦接收到信号就会打断原来的程序执行来按照信号进行处理。
简化术语,信号是一个事件,用于中断运行功能的执行。信号始终在主Python线程中执行。对于信号,这里不做详细介绍。
Python封装了操作系统的信号功能的库 singal 的库。singal 库可以使我们在python程序中中实现信号机制。
Python的信号处理
首先需要了解Python为什么要提供 signal Library。信号库使我们能够使用信号处理程序,以便当接收信号时都可以执行自定义任务。
Mission:当接收到信号时执行信号处理方法
可以通过使用 signal.singal() 函数来实现此功能
Python对信号的处理
通常情况下Python 信号处理程序总是会在主 Python 主解析器的主线程中执行,即使信号是在另一个线程中接收的。 这意味着信号不能被用作线程间通信的手段。 你可以改用 threading 模块中的同步原语。
Python信号处理流程,需要对信号处理程序(signal handling )简要说明。signal handling 是一个任务或程序,当检测到特定信号时,处理函数需要两个参数,即信号id signal number (Linux 中 1-64),与堆栈帧 frame。通过相应信号启动对应 signal handling ,signal.signal() 将为信号分配 处理函数。
如:当运行一个脚本时,取消,此时是捕获到一个信号,可以通过捕获信号方式对程序进行异步的优雅处理。通过将信号处理程序注册到应用程序中:
import signal
import time
def handler(a, b): # 定义一个signal handling
print("Signal Number:", a, " Frame: ", b)
signal.signal(signal.SIGINT, handler) # 将handle分配给对应信号
while True:
print("Press ctrl + c")
time.sleep(10)

如果不对对应信号进行捕获处理时,python将会抛出异常。
root@Seal:/mnt/d/pywork/signal# python signal.py
^CTraceback (most recent call last):
File "signal.py", line 3, in <module>
while True:
KeyboardInterrupt
信号枚举
信号的表现为一个int,Python的信号库有对应的信号枚举成员
其中常用的一般有,
SIGINT control+c
SIGTERM 终止进程 软件终止信号
SIGKILL 终止进程 杀死进程
SIGALRM 超时
| 信号 | 说明 |
|---|---|
| SIG_DFL | |
| SIG_IGN | 标准信号处理程序,它将简单地忽略给定的信号 |
| SIGABRT SIGIOT |
来自 abort 的中止信号。 abort 导致异常进程终止。通常由检测内部错误或严重破坏约束的库函数调用。例如,如果堆的内部结构被堆溢出损坏, malloc()将调用abort() |
| SIGALRM SIGVTALRM SIGPROF |
如果你用 setitimer 这一类的报警设置函数设置了一个时限,到达时限时进程会接收到 SIGALRM, SIGVTALRM 或者 SIGPROF。但是这三个信号量的含义各有不同,SIGALRM 计时的是真实时间,SIGVTALRM计时的是进程使用了多少CPU时间,而 SIGPROF 计时的是进程和代表该进程的内核用了多少时间。 |
| SIGBUS | 总线发生错误时,进程接收到一个SIGBUS信号。举例来说,存储器访问对齐或者或不存在对应的物理地址都会产生SIGBUS信号。 |
| SIGCHLD | 当子进程终止、被中断或被中断后恢复时,SIGCHLD信号被发送到进程。该信号的一个常见用法是指示操作系统在子进程终止后清理其使用的资源,而不显式调用等待系统调用。 |
| SIGILL | 非法指令。当进程试图执行非法、格式错误、未知或特权指令时,SIGILL信号被发送到该进程。 |
| SIGKILL | 发送SIGKILL信号到一个进程可以使其立即终止(KILL)。与SIGTERM和SIGINT相不同的是,这个信号不能被捕获或忽略,接收过程在接收到这个信号时不能执行任何清理。 以下例外情况适用: |
| SIGINT | 来自键盘的中断 (CTRL + C)。KeyboardInterrupt |
| SIGPIPE | 当一个进程试图写入一个没有连接到另一端进程的管道时,SIGPIPE信号会被发送到该进程。 |
| **SIGTERM ** | 终结信号。 KILL -15 |KILL |
| SIGUSR1 SIGUSR2 |
用户自定义信号 |
| SIGWINCH | 终端窗口大小已变化 |
| SIGHUP | 在控制终端上检测到挂起或控制进程的终止。 |
Reference:[signal-wikipedia](
信号函数
Python的信号库中也有很多常用的函数
signal.alarm(time)
创建一个 SIGALRM 类型的信号,time为预定的时间,设置为0时取消先前设置的定时器
signal.pause()
可以使代码逻辑处理过程睡眠,直到收到信号,然后调用对应的handler。
import signal
import os
import time
def do_exit(sig, stack):
raise SystemExit('Exiting')
signal.signal(signal.SIGINT, signal.SIG_IGN)
signal.signal(signal.SIGUSR1, do_exit)
print('My PID:', os.getpid())
signal.pause()
在执行时,忽略了ctrl + c的信号,对USR1做退出操作
signal.setitimer(which, seconds, interval)
which: signal.ITIMER_REAL,signal.ITIMER_VIRTUAL 或 signal.ITIMER_PROF
seconds:多少秒后触发which。seconds设置为0可以清除which的计时器。
interval:每隔interval秒后触发一次
os.getpid()
获得当前执行程序的pid
Windows下信号的使用
在Linux中,可以通过任何可接受的信号枚举值作为信号函数的参数。在Windows中,SIGABRT, SIGFPE, SIGINT, SIGILL, SIGSEGV, SIGTERM, SIGBREAK。
当signal handling需要参数怎么办
在一些时候,signal handling的操作需要对应主进程传递进来一些函数,而在整个项目中执行过程中的变量与 signal handling不处于一个作用域中,而signal.signal() 不能传递其他的参数,这个时候可以使用 partial 创建一个闭包来解决这个问题。
例如:
import signal
import os
import sys
import time
from functools import partial
"""
这里signal frame默认参数需要放到最后
"""
def signal_handler(test_parameter1, test_parameter2, signal_num, frame):
print "signal {} exit. {} {}".format(signal_num, test_parameter1, test_parameter2)
sys.exit(1)
a=1
b=2
signal.signal(signal.SIGINT, partial(signal_handler, a, b) )
print('My PID:', os.getpid())
signal.pause()
忽略信号
signal定义了忽略接收信号的方法。为了实现信号的处理,需要使用signal.signal() 将默认的信号与signal.SIG_IGN 注册,即可忽略对应的信号中断,kill -9 不可忽略 。
import signal
import os
import time
def receiveSignal(signalNumber, frame):
print('Received:', signalNumber)
raise SystemExit('Exiting')
return
if __name__ == '__main__':
# register the signal to be caught
signal.signal(signal.SIGUSR1, receiveSignal)
# register the signal to be ignored
signal.signal(signal.SIGINT, signal.SIG_IGN)
# output current process id
print('My PID is:', os.getpid())
signal.pause()
常用的信号
import signal
import os
import time
import sys
def readConfiguration(signalNumber, frame):
print ('(SIGHUP) reading configuration')
return
def terminateProcess(signalNumber, frame):
print ('(SIGTERM) terminating the process')
sys.exit()
def receiveSignal(signalNumber, frame):
print('Received:', signalNumber)
return
signal.signal(signal.SIGHUP, readConfiguration)
signal.signal(signal.SIGINT, receiveSignal)
signal.signal(signal.SIGQUIT, receiveSignal)
signal.signal(signal.SIGILL, receiveSignal)
signal.signal(signal.SIGTRAP, receiveSignal)
signal.signal(signal.SIGABRT, receiveSignal)
signal.signal(signal.SIGBUS, receiveSignal)
signal.signal(signal.SIGFPE, receiveSignal)
#signal.signal(signal.SIGKILL, receiveSignal)
signal.signal(signal.SIGUSR1, receiveSignal)
signal.signal(signal.SIGSEGV, receiveSignal)
signal.signal(signal.SIGUSR2, receiveSignal)
signal.signal(signal.SIGPIPE, receiveSignal)
signal.signal(signal.SIGALRM, receiveSignal)
signal.signal(signal.SIGTERM, terminateProcess)
处理python中的信号的更多相关文章
- Python模块之信号学习(signal)
信号概述 在学习Python前应该学习下Linux下的信号,软中断信号(signal,又简称为信号)用来通知进程发生了异步事件.进程之间可以互相通过系统调用kill发送软中断信号.内核也可以因为内部事 ...
- 第15.16节 PyQt(Python+Qt)入门学习:PyQt中的信号(signal)和槽(slot)机制以及Designer中的使用
老猿Python博文目录 老猿Python博客地址 一.引言 前面一些章节其实已经在使用信号和槽了,但是作为Qt中最重要的机制也是Qt区别与其他开发平台的重要核心特性,还是非常有必要单独介绍. 二.信 ...
- python中协程
在引出协成概念之前先说说python的进程和线程. 进程: 进程是正在执行程序实例.执行程序的过程中,内核会讲程序代码载入虚拟内存,为程序变量分配空间,建立 bookkeeping 数据结构,来记录与 ...
- Python中的threading
Python中的threading RLock--重入锁 RLock在Python中的实现是对Lock的封装,具体在类中维护了一个重入次数的变量.一旦一个线程获得一个RLock,该线程再次要求获得该锁 ...
- python中的进程、线程(threading、multiprocessing、Queue、subprocess)
Python中的进程与线程 学习知识,我们不但要知其然,还是知其所以然.你做到了你就比别人NB. 我们先了解一下什么是进程和线程. 进程与线程的历史 我们都知道计算机是由硬件和软件组成的.硬件中的CP ...
- Python中利用LSTM模型进行时间序列预测分析
时间序列模型 时间序列预测分析就是利用过去一段时间内某事件时间的特征来预测未来一段时间内该事件的特征.这是一类相对比较复杂的预测建模问题,和回归分析模型的预测不同,时间序列模型是依赖于事件发生的先后顺 ...
- Python中的并发编程
简介 我们将一个正在运行的程序称为进程.每个进程都有它自己的系统状态,包含内存状态.打开文件列表.追踪指令执行情况的程序指针以及一个保存局部变量的调用栈.通常情况下,一个进程依照一个单序列控制流顺序执 ...
- Python中的multiprocessing和threading
Python中的multiprocessing和threading分别使用来实现多进程编程和多线程编程的.其中threading比较简单,而前者比较繁琐. 下面,我们进行一下分析: 多线程--thre ...
- 【转】Python中执行cmd的三种方式
原文链接:http://blog.csdn.net/menglei8625/article/details/7494094 目前我使用到的python中执行cmd的方式有三种: 1. 使用os.sys ...
随机推荐
- Android面试必问!View 事件分发机制,看这一篇就够了!
在 Android 开发当中,View 的事件分发机制是一块很重要的知识.不仅在开发当中经常需要用到,面试的时候也经常被问到. 如果你在面试的时候,能把这块讲清楚,对于校招生或者实习生来说,算是一块不 ...
- 常用的HTML标记
一.格式标记 1.<br> <br>是一个单标记,用来强制换行. 2.<p> <p>是双标记.用来换分段落. 3.<center> < ...
- K8S的资源管理
K8S的资源管理 管理K8S资源的三种基本方法: 陈述式资源管理方法-使用cli工具进行管理. 声明式资源管理方式-主要依耐资源配置清单. GUI式资源管理方法-主要依耐图形界面. 陈述式资源管理方法 ...
- Windows(受控主机)上配置
Powershell版本要求及配置 windows需要使用Powershell4.0及以上版本,入下图所示,如果不是4.0及以上的需要升级 一.升级Powershell至3.0+ 1. 下载并安装Mi ...
- 如何在我的EC2实例状态更改时获取自定义电子邮件通知
具体详情,请参见: https://amazonaws-china.com/cn/premiumsupport/knowledge-center/ec2-email-instance-state-ch ...
- Elasticsearch + Logstash + Kibana +Redis +Filebeat 单机版日志收集环境搭建
1.前置工作 1.虚拟机环境简介 Linux版本:Linux localhost.localdomain 3.10.0-862.el7.x86_64 #1 SMP Fri Apr 20 16:44:2 ...
- 测试开发:从0到1学习如何测试API网关
本文来自我的一名学员分享 日常工作中,难免会遇到临危受命的情况,虽然没有这么夸张,但是也可能会接到一个陌生的任务,也许只是对这个概念有所耳闻.也许这个时候会感到一丝的焦虑,生怕没法完成领导交给的测试任 ...
- Dubbo以及Zookeeper安装
1.什么是Dubbo? Apache Dubbo 是一款高性能.轻量级的开源 Java 服务框架 提供了六大核心能力:面向接口代理的高性能RPC调用,智能容错和负载均衡,服务自动注册和发现,高度可扩展 ...
- mysql-redis连接
# log 数据库连接 class LogMysql(object): conn = None cursor = None def __init__(self): self.conn = pymysq ...
- Go语言web开发---Beego的cookie
1.简介 (1)Http是无状态的协议,服务器不能记录浏览器的访问状态,也就是说服务器不能区分两次请求是否是同一个客户端,这样的设计严重阻碍了web程序的设计. (2)Cookie是解决Http协议无 ...