signal,blinker:信号(看我脸色行事)
signal
什么是信号(signal)?
信号在linux中被用来进行进程间的通信和异步处理,简单地可以理解会为回调函数,当发送一个信号时,会触发相应的操作。python中的signal模块便是用来处理信号的,需要注意的是,这个模块不能在Windows上使用,因为Windows内核对信号的支持不是很好,这里我们使用Linux进行操作。
python的signal模块所支持的信号
python中支持的信号很多,基本和linux内置的信号是一致的,但是常用的如下
SIGHUP
:连接挂断本信号在用户终端连接结束时发出。我们通常连接linux的时候,系统会分配给用户一个终端(session)。在这个终端运行的所有程序,包括前台进程组和后台进程组,都属于这个session。当用户退出linux时,无论前台还是后台,凡是有对终端输出的进程都会收到SIGHUP信号。这个信号的默认操作为终止进程,因此会向终端输出内容的那些进程就会终止。不过有的进程可以捕捉这个信号并忽略它。比如wget,这样就算退出了linux登录,wget依旧能继续下载
SIGILL
:非法指令执行了非法指令,通常是因为可执行文件本身出现错误,或者执行数据段,堆栈溢出时也可能产生这个信号
SIGINT
:终止进程(ctrl c)程序终止(interrupt)信号,通常在用户按下ctrl c的时候发出,用于通知前台进程组终止进程
SIGTSTP
:暂停进程(ctrl z)停止进程的运行, 但该信号可以被处理和忽略。通常在用户按下ctrl z的时候触发
SIGKILL
:杀死进程(此信号不能被捕获或忽略)用来立即结束程序的运行,本信号无法被阻塞、处理和忽略。如果管理员发现某个进程终止不了,可尝试发送这个信号。
SIGQUIT
:终端退出和SIGINT类似,但通常是由ctrl /来通知,进程在因收到SIGQUIT退出时会产生core文件,在这个意义上类似于一个程序错误信号
SIGTERM
:杀死进程(可以被捕获或忽略)程序结束(terminate)信号,与SIGKILL不同的是,该信号可以被阻塞、处理、忽略。通常用来要求程序自己正常退出。比如shell中,kill 进程id会产生这个信号。如果这个无法终止,我们才会尝试SIGKILL,相当于kill -9 进程id
SIGALRM
:闹钟信号,由signal.alarm()发起时钟定时信号, 计算的是实际的时间或时钟时间. alarm函数使用该信号.
SIGCONT
:继续执行暂停的进程让一个停止(stopped)的进程继续执行. 本信号不能被阻塞. 可以用一个handler来让程序在由stopped状态变为继续执行时完成特定的工作
除此之外还有很多其他信号,这里不一一列举了,有兴趣的话可以在网上搜索,linux 信号
signal模块所支持的函数
alarm(time),time为int,表示多少秒,在时间过后,向进程自身发送SIGALRM信号
import signal
import time
signal.alarm(3) # 3s后会向进程自身发出一个SIGALRM信号,同时终止程序
while 1:
time.sleep(1)
print(".......")
"""
.......
.......
Alarm clock
"""
pause(),让进程暂停,以等待信号(什么信号都行)。因此该函数相当于阻塞进程进行,接收到信号后继续前进。
import signal
signal.pause() # 程序会卡在这里
print(123)
signal(signalnum, handler)
这是一个非常重要的函数,用来注册信号的。signalnum是要注册的信号量,handler是该信号量所对应的处理器,一般是一个可以调用的函数,必须要接收两个参数,分别是信号量(signalnum)、当前程序运行的堆栈(frame),这两个参数会在触发信号时自动传入。
那如果我们想忽略信号的话,就是直接在handler的函数体中写一个pass吗?这样是可以的,但是signal为我们提供了两个常量,之前没有介绍。
1.signal.SIG_DFL:表示接收到信号后,程序按照默认行为执行;
2.signal.SIG_IGN:表示接收到信号后,程序忽略该信号,继续自身运行。
但是需要注意的是:
1.该方法是有返回值的,返回之前原有的信号处理函数
2.该方法只能在主线程中注册,如果在子线程中注册, 会引发一个ValueError
# -*- coding:utf-8 -*-
# @Author: WanMingZhu
# @Date: 2019/8/30 17:12
import signal
import traceback
def handler(signalnum, frame):
print(signalnum)
print(frame)
traceback.print_stack(frame) # 打印栈帧的方法
# 注册一个signal.SIGALRM信号
signal.signal(signal.SIGALRM, handler)
# 如何发送信号
# 可以使用os.kill
import os
# 向当前进程发送信号
os.kill(os.getpid(), signal.SIGALRM)
"""
输出结果:
14
<frame at 0x7fda528cb9f8, file '1.py', line 19, code <module>>
File "1.py", line 19, in <module>
os.kill(os.getpid(), signal.SIGALRM)
"""
blinker
不同于signal模块,blink是第三方模块。个人觉得blink使用起来要比signal简单许多,而且这个模块可以在Windows下使用
# -*- coding:utf-8 -*-
# @Author: WanMingZhu
# @Date: 2019/8/30 17:12
from blinker import Namespace
# 1.定义信号
namespace = Namespace()
fire = namespace.signal("fire")
# 2.监听信号
# 首先定义一个回调函数,里面至少要接收一个参数
def open_fire(sender):
print(sender)
print("open_fire")
# 监听
fire.connect(open_fire)
# 3.发送信号
# send里面的参数则会传给open_fire
fire.send("xxx")
"""
输出结果:
xxx
open_fire
"""
总结一下:步骤就三步
1.定义信号
namespace = NameSpace()
signal = namespace.signal("signal")
2.监听信号
创建需要至少要接收一个参数的函数,然后通过signal.connect进行注册
3.发送信号
调用signal.send("message")方法,然后会触发绑定的函数,同时message也会传进去,如果不传则为None
如果回调函数里面只有一个参数,又不想传的话,直接send即可,会自动将None传进去
但是如果回调函数要接收多个参数,那么第一个sender必须通过位置参数指定,其余要通过关键字参数指定
from blinker import Namespace
# 1.定义信号
namespace = Namespace()
fire = namespace.signal("fire")
def open_fire(sender, a, b, c):
print(sender, a, b, c)
print("open fire`````")
fire.connect(open_fire)
# 回调至少接受一个参数,且必须通过位置参数指定
# 如果不传则相当于传了一个None
# 如果有多个参数,那么剩余的参数要通过关键字参数的方式来传递
try:
fire.send("xxx", 1, 2, 3)
except TypeError as e:
print(e) # send() accepts only one positional argument, 4 given
fire.send("xxx", a=1, b=2, c=3)
"""
xxx 1 2 3
open fire`````
"""
# 第一个参数不指定,则默认传了一个None进去
fire.send(a=1, b=2, c=3)
"""
None 1 2 3
open fire`````
"""
signal,blinker:信号(看我脸色行事)的更多相关文章
- flask使用blinker信号机制解耦业务代码解决ImportError: cannot import name 'app',以异步发送邮件为例
百度了大半天,不知道怎么搞,直到学习了blinker才想到解决办法,因为之前写java都是文件分开的, 所以发送邮件业务代码也放到view里面,但是异步线程需要使用app,蛋疼的是其他模块不能从app ...
- python signal(信号)
信号的概念 信号(signal)-- 进程之间通讯的方式,是一种软件中断.一个进程一旦接收到信号就会打断原来的程序执行流程来处理信号. 几个常用信号: SIGINT 终止进程 中断进 ...
- 主机开启后,显示器显示NO SIGNAL,无信号
第一个原因:有可能是主机和显示器的连线接触不良(特别是接口处没有插好或者松动),还有可能这根连接的数据线出现问题,所以才会出现没有信号输入到屏幕,无显示,黑屏,处理方法:重新拨插一下这根连接的数据线, ...
- signal, sigaction,信号集合操作
信号是与一定的进程相联系的,而建立其信号和进程的对应关系,这就是信号的安装登记. Linux主要有两个函数实现信号的安装登记:signal和sigaction.其中signal在系统调用的基础上实现, ...
- Azure IoT带来更高效的新能源生产和会看人脸色的无人超市
全球分析机构都认为物联网将在未来几年呈现爆发式增长,到2020年,各种传感器.新型物联网设备,再加上传统PC.智能手机.平板电脑.网络电视,以及各类可穿戴智能设备,将交织成一个由300亿到500亿台设 ...
- signal - 有效信号的清单
描述 (DESCRIPTION) 下面 列出 Linux 支持的 信号. 某些 信号 依赖于 体系结构(architecture). 首先, POSIX.1 描述了 下列 信号. 信号 值 动作 说明 ...
- funhub 独立游戏团队诚邀策划,美术,技术,QA 大大加入(可远程办公)
我们刚成立的的独立游戏团队,base:广州,团队陆陆续续已经有 6 个成员了,现在还缺的岗位有策划,美术.不过有其 他岗位的仁人志士也可加入. 另外,我们支持远程办公,这是互联网行业的天然优势,一定要 ...
- 进程间通信之信号量、消息队列、共享内存(system v的shm和mmap)+信号signal
进程间通信方式有:System v unix提供3种进程间通信IPC:信号量.消息队列.共享内存.此外,传统方法:信号.管道.socket套接字. [注意上述6种方式只能用户层进程间通信.内核内部有类 ...
- [学习笔记]信号基本概念(中断和信号)/名称及常用信号/信号处理/signal函数实践
1基本概念 中断 q 中断是系统对于异步事件的响应 q 中断信号 q 中断源 q 现场信息 q 中断处理程序 q 中断向量表 异步事件的响应:进程执行代码的过程中可以随时被打断,然后去执行 ...
随机推荐
- .NET制作滚动条
今天,在工作的时候,刚好做到了滚动条,对这点不是很懂,所以,研究了一下,记录在这里,与大家分享. 对于前台页面,我们就只需要设置数据表的样式:style="overflow: auto; 即 ...
- HTTP及WEB框架简述
HTTP介绍 Hyper Text Transfer Protocol,超文本传输书协议,是万维网数据通信的基础,规定了请求和响应标准. HTTP工作原理 HTTP 请求以及响应的步骤 客户端连接到W ...
- 通过URLOS安装Redis缓存为wordpress网站提速
快!快!快!我们都知道网站的加载速度直接影响用户体验.据研究发现,网站页面在3秒内加载完毕对用户而言是最佳的浏览体验.如果超过这个时间,用户跳出网站的几率会非常大.所以对于站长来说,提高速度是他们追求 ...
- 差分+贪心:IncDec序列
原题 题目描述给定一个长度为 n 的数列 a1,a2,…,ana1,a2,…,an,每次可以选择一个区间 [l,r][l,r],使下标在这个区间内的数都加一或者都减一. 求至少需要多少次操作才能使数列 ...
- eclipse 导入项目出现的问题汇总
Unbound classpath variable: 'TOMCAT_HOME' in project XXX Problem 翻译:未绑定的类路径变量:项目XXX中的“TOMCAT_HOME” 解 ...
- java application.properties 密码加密
main方法 public static void main(String[] args) { BasicTextEncryptor textEncryptor = new BasicTextEncr ...
- Column常用的参数
#encoding: utf-8 from sqlalchemy import create_engine,Column,Integer,String,DateTime from sqlalchemy ...
- (5.3)mysql高可用系列——mysql复制之复制的参数
参考:https://www.iteye.com/blog/shift-alt-ctrl-2269539 详情 [1]参数 #[1.1]基本参数 bind-address=192.168.1.201 ...
- Struts 2访问Servlet API
在servlet中可以通过servlet API来获取Session,在Struts中如何获取Session呢? 解析:将用户名放入session 两种方案 1. 与Servlet API解耦的访问方 ...
- 设计模式:状态模式(Status)
在介绍状态模式之前,我们先来看这样一个实例:你公司力排万难终于获得某个酒店的系统开发项目,并且最终落到了你的头上.下图是他们系统的主要工作(够简单). 当你第一眼看到这个系统的时候你就看出来了这是一个 ...