信号signal 是python进程间通信多种机制中的其中一种机制。可以对操作系统进程的控制,当进程中发生某种原因而中断时,可以异步处理这个异常。

信号通过注册的方式‘挂’在一个进程中,并且不会阻塞该进程的运行。一个进程一旦接收到其他进程(可能是应用中的其他进程,也可能使操作系统中的进程)发送的信号就会打断原来的程序执行流程来处理这个信号。

名词理解:

异步: 程序在执行中利用内核功能帮助完成必要的辅助操作,不影响应用层持续执行

注意: 这里的同步和异步机制是相对多进程而言的。

在多个进程中通信的机制中,只有singal是异步执行的,另外python进程间通信的机制还有pipe(管道),queue(队列),value(共享空间)等等。

signal可以用在什么地方?

siganl的应用:

1. 故障定位技术(进程的底层故障,例如进程突然中断和一些可能性较小的故障)

2. 对进程的流程控制 

首先说说与信号signal有关的几个函数

(1)os.kill(pid,sig)

发送一个信号给某个进程

参数解析:

pid 指定发送信号的进程号

sig  要发送的信号代号(需要通过signal模块获取)

(2)signal.alarm(sec)  非阻塞函数

设置时钟信号,在一定时间后给自身发送一个SIGALRM信号

原理: 时钟的创建是进程交由操作系统内核(kernal)帮助创建的

时钟和进程之间是异步执行的,当时钟到时,内核会发送信号给进程,进程接收信号进行相应的响应操作。

注意:如果设置多个时钟,后面的时钟会覆盖前面的时钟,一个进程只有一个挂起的时钟。

(3)signal.pause()

阻塞进程,等待一个信号.当接收到信号时就会停止阻塞

例如:等待signal()函数的发送

(4)signal.signal(sig,handler)

这是信号中最关键的一个方法,用于声明一个信号。当进程运行过程中出现故障异常或者需要进程间通信时,由操作系统内核中的进程或者应用中的进程发出处理信号,通知注册了信号的进程进行处理。

signal.signal(sig,handler)

参数理解:

sig 要处理的信号名称

handler 信号处理方法

可选值: SIG_DFL    表示默认方法处理

SIG_IGN    表示忽略这个信号(一般为了避免父进程和子进程的互相干扰而使用)

handler       自定义回调函数

 

自定义回调函数handler:

这个是当用于在进程捕捉到其他进程发送的信号时调用的函数,当此函数返回时,进程继续继续按原来的逻辑顺序执行。此函数在定义时python普通函数的定义没有区别。函数名不一定是handler,但作为作为参数传入signal()方法的参数名一定是与定义handler函数的函数相同。

def  handler(signum,frame):

do  something…

1)sig :接收到的信号编号,signal模块内部定义了一些常用的内核信号,并为它们进行了编号。

例如:

windows操作系统下

SIGNALINT编号为2

>>>signal.SIGINT

<Signals.SIGINT: 2>

SIGBREAK编号为21

>>>signal.SIGBREAK

<Signals.SIGBREAK: 21>

注意:windows操作系统没有SIGUSR1和SIGUSR2这两个型号类型,linux操作系统才有。

2) frame:信号结构对象(可以通过结构对象查看信号信息,基本不用)

signal函数实际上是一个异步的回调函数,只要执行了该函数,则进程任意时候接收到相应信号都会处理。 这里的异步就是上文提到的异步机制,是计算机内核程序与本进程间同时运行,互相不干扰的一种机制,对于进程的正常执行有着关键的作用。这种异步机制在任何后端编程语言中都是存在的,只不过实现的方式和细节不一样而已。

singnal怎么用?

一般信号signal是在需要检测异常的程序的开头就定义好了,程序顺序向下运行时,一旦捕获到操作系统发出的signal或者其他进程发出的signal,马上就会停止当前的程序运行状态,去处理捕获到的signal。

案例:
注册signal
import signal
import os
import time print("The process's PID is:",os.getpid())
def handle_signal(signum,frame):
print('Received and handle:',signum) #注册信号处理程序
signal.signal(signal.SIGUSR1,handle_signal)
signal.signal(signal.SIGUSR2,handle_signal) print("The process's PID is:",os.getpid()) while True:
print('Waiting...')
print(time.ctime())
time.sleep(2)
终端分别输入输入:
>>> os.kill(7094,signal.SIGUSR1)
>>> os.kill(7094,signal.SIGUSR2)

结果:

Waiting...
Sat Nov 17 12:19:26 2018
Waiting...
Sat Nov 17 12:19:28 2018
Received and handle: 10
Waiting...
Sat Nov 17 12:19:30 2018 Waiting...
Sat Nov 17 12:22:21 2018
Received and handle: 12
Waiting...
Sat Nov 17 12:22:23 2018

处理interrupt

import signal
import os
import sys
import time print("The process's PID is:",os.getpid()) def handle_signal(signum,frame):
print('Received and handle:',signum) def handle_interrupt(signum,frame):
print('Receive keyboard interrupt')
sys.exit(0) #退出进程 #注册信号处理程序
signal.signal(signal.SIGINT,handle_interrupt)
signal.signal(signal.SIGUSR1,handle_signal) while True:
print('Waiting...')
print(time.ctime())
time.sleep(2)

终端输入:

>>> os.kill(7625,signal.SIGINT)

会退出进程

如果注册函数改为

signal.signal(signal.SIGINT,signal.SIG_IGN)

则会忽略终端发出的SIGINT

时钟

给signal设定时钟
def handle_signal(signum,frame):
print('Time is up!',signum)
sys.exit() signal.signal(signal.SIGALRM,handle_signal)
signal.alarm(3) while True:
print(time.ctime())
time.sleep(1)

结果:

Sat Nov 17 13:21:51 2018
Sat Nov 17 13:21:52 2018
Sat Nov 17 13:21:53 2018
Time is up! 14

附录:

windows下的sig信号类型

>>> dir(signal)

['CTRL_BREAK_EVENT', 'CTRL_C_EVENT', 'Handlers', 'NSIG', 'SIGABRT', 'SIGBREAK', 'SIGFPE', 'SIGILL', 'SIGINT', 'SIGSEGV', 'SIGTERM', 'SIG_DFL', 'SIG_IGN', 'Signals', '_IntEnum', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '_enum_to_int', '_int_to_enum', '_signal', 'default_int_handler', 'getsignal', 'set_wakeup_fd', 'signal']

linux下的sig信号类型

>>> dir(signal)

['ITIMER_PROF', 'ITIMER_REAL', 'ITIMER_VIRTUAL', 'ItimerError', 'NSIG', 'SIGABRT', 'SIGALRM', 'SIGBUS', 'SIGCHLD', 'SIGCLD', 'SIGCONT', 'SIGFPE', 'SIGHUP', 'SIGILL', 'SIGINT', 'SIGIO', 'SIGIOT', 'SIGKILL', 'SIGPIPE', 'SIGPOLL', 'SIGPROF', 'SIGPWR', 'SIGQUIT', 'SIGRTMAX', 'SIGRTMIN', 'SIGSEGV', 'SIGSTOP', 'SIGSYS', 'SIGTERM', 'SIGTRAP', 'SIGTSTP', 'SIGTTIN', 'SIGTTOU', 'SIGURG', 'SIGUSR1', 'SIGUSR2', 'SIGVTALRM', 'SIGWINCH', 'SIGXCPU', 'SIGXFSZ', 'SIG_DFL', 'SIG_IGN', '__doc__', '__name__', '__package__', 'alarm', 'default_int_handler', 'getitimer', 'getsignal', 'pause', 'set_wakeup_fd', 'setitimer', 'siginterrupt', 'signal']

常用信号类型解析

SIGHUP   断开连接

SIGINT    ctrl-C

SIGUIT    ctrl-\

SIGTSTP   ctrl-z

SIGKILL    终止进程且不能被处理

SIGSTOP   暂停进程且不能被处理

SIGALRM   时钟进程

SIGCHLD   子进程状态改变发送给父进程信息号(但一般父进程不会处理)

参考文章:

https://www.cnblogs.com/xautxuqiang/p/5339602.html

https://www.cnblogs.com/madsnotes/articles/5688681.html

python进程间通信--信号Signal的更多相关文章

  1. Linux进程间通信(一): 信号 signal()、sigaction()

    一.什么是信号 用过Windows的我们都知道,当我们无法正常结束一个程序时,可以用任务管理器强制结束这个进程,但这其实是怎么实现的呢?同样的功能在Linux上是通过生成信号和捕获信号来实现的,运行中 ...

  2. Python标准库07 信号 (signal包,部分os包)

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 在了解了Linux的信号基础之后,Python标准库中的signal包就很容易学习 ...

  3. 进程间通信之信号量、消息队列、共享内存(system v的shm和mmap)+信号signal

    进程间通信方式有:System v unix提供3种进程间通信IPC:信号量.消息队列.共享内存.此外,传统方法:信号.管道.socket套接字. [注意上述6种方式只能用户层进程间通信.内核内部有类 ...

  4. Linux进程间通信之管道(pipe)、命名管道(FIFO)与信号(Signal)

    整理自网络 Unix IPC包括:管道(pipe).命名管道(FIFO)与信号(Signal) 管道(pipe) 管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道 ...

  5. python练习笔记——利用信号signal处理僵尸进程

    1 signal处理僵尸进程的基于语法 利用信号signal处理僵尸进程的方法:signal(SIGCHLD,SIG_IGN),该方法也是第三种处理僵尸进程的方法. SIGCHLD:子进程状态改变后产 ...

  6. python模块之signal信号

    简介 作用:发送和接收异步系统信号 信号是一个操作系统特性,它提供了一个途径可以通知程序发生了一个事件并异步处理这个事件.信号可以由系统本身生成,也可以从一个进程发送到另一个进程. 由于信号会中断程序 ...

  7. Python进程间通信和网络基础

    Python进程间通信和网络基础 Python支持多种进程间通讯的方式, 有单机通信的signal和mmap等, 也有可以通过网络的socket方式, 这里先介绍select等的有关知识, socke ...

  8. Linux进程间通信——信号集函数

    一.什么是信号 用过Windows的我们都知道,当我们无法正常结束一个程序时,可以用任务管理器强制结束这个进程,但这其实是怎么实现的呢?同样的功能在Linux上是通过生成信号和捕获信号来实现的,运行中 ...

  9. 详解linux进程间通信-信号

    前言:之前说看<C++ Primer >暂时搁浅一下,迷上公司大神写的代码,想要明白,主要是socket.进程间通信! 知道进程间通信:信号.信号量.管道.消息队列.共享内存(共享存储), ...

随机推荐

  1. 《机器学习实战(基于scikit-learn和TensorFlow)》第四章内容的学习心得

    本章主要讲训练模型的方法. 线性回归模型 闭式方程:直接计算最适合训练集的模型参数 梯度下降:逐渐调整模型参数直到训练集上的成本函数调至最低,最终趋同与第一种方法计算出的参数 首先,给出线性回归模型的 ...

  2. JS 数据类型和数据分析

    栈区:(stack)-由编译器自动分配释放,存放函数的参数值,局部变量的值等. 特点是存放体积小,使用频率高的数据.可以类比内存. 堆区:(heap)-一般由程序员分配释放,若开发者不释放,程序结束时 ...

  3. HttpClient和HttpURLConnection的使用和区别(下)

    转自来自点击打开链接 接着上一篇,我们继续来分析HttpURLConnection的使用,以及两者的共同点和区别. 目录 用法 HttpURLConnection 区别 引用资料 用法 HttpURL ...

  4. LeetCode--No.001 Two Sum

    Two Sum Total Accepted: 262258 Total Submissions: 1048169 Difficulty: Easy Given an array of integer ...

  5. Spark基础脚本入门实践3:Pair RDD开发

    Pair RDD转化操作 val rdd = sc.parallelize(List((1,2),(3,4),(3,6))) //reduceByKey,通过key来做合并val r1 = rdd.r ...

  6. Intellij-忽略其他编译错误,运行当前文件

    在使用Intellij IDEA的时候,有时候想在项目中写个main()方法或者单元测试测试个功能,但是有其他文件编译出错IDEA就提示我说不能运行,很是烦恼. 能不能像Eclipse一样呢,其他编译 ...

  7. 2018.4.24-ml笔记(多元线性回归)

    numpy.dot作用于两个向量则是它们内积,作用于矩阵则是矩阵积. RMSE解决量纲问题,即单位 RMSE会放大差值比较大的值,所以选用MSE更好.

  8. salesforce零基础学习(八十八)项目中的零碎知识点小总结(二)

    通过做项目以及群里面的一些大神的聊天,总结一下关于项目中的两个知识点,以后当做参考. 一. 在custom setting中配置集成接口信息后刷sandbox的问题 我们做项目时,经常会遇见和其他平台 ...

  9. 初识Quartz (一)

    首先大概的了解一下Quartz. 一:首先进入官网去看看什么是quartz.http://www.quartz-scheduler.org/ Quartz是一个功能丰富的开源作业调度库,可以集成到几乎 ...

  10. webpack4打包报错:WARNING in configuration The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults fo

    运行命令webpack ./src/main.js ./dist/murenziwei.js后,目录上神马动静都没有,你以为在dist文件夹上会有murenziwei.js吗?毛都没有 警告和错误倒是 ...