`
san_yun
  • 浏览: 2653785 次
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

python 信号量

 
阅读更多

    最近有一个需求,在python程序被关闭之前加一个钩子做一些清理工作。上网搜索了一下,发现atexit模块只能在程序正常结束才能触发,但如果程序被kill掉之后却不会被触发。后来研究了一下可以通过信号量来处理,python 提供了signal模块。

 

信号的概念

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

几个常用信号:

SIGINT     终止进程  中断进程  (control+c)

SIGQUIT   退出进程

SIGTERM   终止进程     软件终止信号  (默认信号)

SIGKILL   终止进程     杀死进程

SIGALRM 闹钟信号

当直接写kill PID,默认是SIGTERM

 

进程结束信号 SIGTERM和SIGKILL的区别

SIGTERM比较友好,进程能捕捉这个信号,根据您的需要来关闭程序。在关闭程序之前,您可以结束打开的记录文件和完成正在做的任务。在某些情况下,假如进程正在进行作业而且不能中断,那么进程可以忽略这个SIGTERM信号。

对于SIGKILL信号,进程是不能忽略的。这是一个 “我不管您在做什么,立刻停止”的信号。假如您发送SIGKILL信号给进程,Linux就将进程停止在那里。

 

发送信号一般有两种原因:

1(被动式)  内核检测到一个系统事件.例如子进程退出会像父进程发送SIGCHLD信号.键盘按下control+c会发送SIGINT信号

2(主动式)  通过系统调用kill来向指定进程发送信号

 

linux操作系统提供的信号

[100003@oss235 myppt]$ kill -l

 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL

 5) SIGTRAP      6) SIGABRT      7) SIGBUS       8) SIGFPE

 9) SIGKILL     10) SIGUSR1     11) SIGSEGV     12) SIGUSR2

13) SIGPIPE     14) SIGALRM     15) SIGTERM     16) SIGSTKFLT

17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP

21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU

25) SIGXFSZ     26) SIGVTALRM   27) SIGPROF     28) SIGWINCH

29) SIGIO       30) SIGPWR      31) SIGSYS      34) SIGRTMIN

35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3  38) SIGRTMIN+4

39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8

43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12

47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14

51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10

55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7  58) SIGRTMAX-6

59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2

63) SIGRTMAX-1  64) SIGRTMAX

Python提供的信号

Python 2.4.3 (#1, Jun 11 2009, 14:09:58)

[GCC 4.1.2 20080704 (Red Hat 4.1.2-44)] on linux2

Type "help", "copyright", "credits" or "license" for more information.

>>> import signal

>>> dir(signal)

['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__', 'alarm', 'default_int_handler', 'getsignal', 'pause', 'signal']

操作系统规定了进程收到信号以后的默认行为

但是,我们可以通过绑定信号处理函数来修改进程收到信号以后的行为

有两个信号是不可更改的SIGTOP和SIGKILL

 

 

绑定信号处理函数

 

#!/usr/bin/env python

import atexit
from signal import signal, SIGTERM

def test():
        print 'exit........'
atexit.register(test)
signal(SIGTERM, lambda signum, stack_frame: exit(1))

while True:
        pass

 

运行该程序。然后通过另外一个进程来发送信号。

发送信号

发送信号的代码如下:

import os  
import signal  
   
#发送信号,16175是前面那个绑定信号处理函数的pid,需要自行修改  
os.kill(16175,signal.SIGTERM)  
#发送信号,16175是前面那个绑定信号处理函数的pid,需要自行修改  
os.kill(16175,signal.SIGUSR1) 

 

SIGKILL信号

python提供了SIGKILL这个常量,但是无法使用,尝试运行这面代码报错:

signal.signal(signal.SIGKILL,test):

 

File "test_atexit.py", line 13, in <module>
    signal.signal(signal.SIGKILL,test)
RuntimeError: (22, 'Invalid argument')

So... Python自己并不检查SIGKILL,而是直接把底层标准C的运行时错误返回。
SIGKILL无法捕捉,而且无法忽略。

 

SIGCHLD信号

然后显示一个子进程结束后自动向父进程发送SIGCHLD信号的例子。

 

''''' 
子进程结束会向父进程发送SIGCHLD信号 
'''  
import os  
import signal  
from time import sleep  
   
def onsigchld(a,b):  
    print '收到子进程结束信号'  
signal.signal(signal.SIGCHLD,onsigchld)  
   
pid = os.fork()  
if pid == 0:  
   print '我是子进程,pid是',os.getpid()  
   sleep(2)  
else:  
    print '我是父进程,pid是',os.getpid()  
    os.wait()  #等待子进程结束  

 

使用信号需要特别注意的地方

如果一个进程收到一个SIGUSR1信号,然后执行信号绑定函数,第二个SIGUSR2信号又来了,第一个信号没有被处理完毕的话,第二个信号就会丢弃。所以,尽量不要在多线程中使用信号。

 

Alarms信号

Alarms 是一个特殊信号类型,它可以让程序要求系统经过一段时间对自己发送通知。os 标准模块中指出,它可用于避免无限制阻塞 I/O 操作或其它系统调用。

像下面例子,原本程序睡眠 10 后才打印出 print 'After :', time.ctime(),但是由于 signal.alarm(2),所以 2 秒后就执行了打印。

 

import signal
import time

def receive_alarm(signum, stack):
    print 'Alarm :', time.ctime()

# Call receive_alarm in 2 seconds
signal.signal(signal.SIGALRM, receive_alarm)
signal.alarm(2)

print 'Before:', time.ctime()
time.sleep(10)
print 'After :', time.ctime()
 

参考:

http://blog.csdn.net/liangguohuan/article/details/7099978

http://guozhiwei.iteye.com/blog/939008

http://code.activestate.com/recipes/533117-cleaning-up-when-killed/

分享到:
评论

相关推荐

    信号量同步实验报告(哲学家进餐问题避免死锁的三种方法)

    操作系统初学,关于信号量同步的实验报告,用三种方法避免哲学家进餐问题死锁,a:and信号量,b:控制进餐人数,c设置条件

    python线程信号量semaphore使用解析

    Python中的线程信号量(Semaphore)是多线程编程中的一种同步机制,它主要用于控制对共享资源的访问,以防止过多的线程同时访问而导致资源竞争。信号量维护了一个内部计数器,该计数器表示可以并发访问的资源数量。...

    timesignal_Python信号_python_信号提取_时域信号特征_

    时域信号特征通常包括一系列描述信号基本特性的量,它们能够帮助我们理解和解析信号的内在结构,为后续的分析和预测提供有效输入。 首先,我们要理解什么是时域信号。时域信号是指在一段时间内,随时间变化的物理量...

    dsp_dsp_python信号处理_信号处理_python_

    在数字信号处理(DSP,Digital Signal Processing)领域,Python已经成为了一种非常流行的工具,因其语法简洁、库丰富以及强大的可视化能力而备受青睐。本压缩包中的内容主要涉及使用Python进行信号处理的相关程序,...

    rt-thread信号量_holecev_RT-Thread_rtthread信号量_信号量_

    - **rtconfig.py**:这是RT-Thread的Python配置工具,可以用来生成rtconfig.h文件,方便用户自定义系统配置,包括信号量的数量和类型。 - **SConscript**、**SConstruct**:这些是构建脚本,用于编译和链接RT-...

    对Python信号处理模块signal详解

    要查看Python中的信号量,可以使用dir(signal)来查看。 signal.signal() 在signal模块中,主要是使用signal.signal()函数来预设信号处理函数 singnal.signal(signalnum, handler) 其中第一个参数是信号量,第二个...

    Python信号与槽、多线程、类学习笔记.pdf

    Python提供了多种同步机制,例如锁(Lock)、信号量(Semaphore)、事件(Event)等,可以用来控制线程间的协作与数据的同步访问。 最后是关于类的学习。Python是一种面向对象的编程语言,类是面向对象编程的基础。...

    信号分析系统python实现版本.zip_python 信号_python 信号系统_python的信号_信号分析系统/pyt

    在信息技术中,信号通常指的是携带信息的数据,可以是声音、图像、温度等物理量。信号分析则是研究这些信号的性质、特征以及提取其中信息的过程。 Python中的信号处理库如`numpy`、`scipy`、`matplotlib`、`pyaudio...

    使用信号量(Semaphore)实现线程的同步

    在Python中,可以使用`threading.Semaphore`类来实现信号量。例如,创建一个计数信号量: ```python import threading semaphore = threading.Semaphore(3) # 创建一个值为3的信号量 def worker(): semaphore....

    Python3.X 线程中信号量的使用方法示例

    ### Python3.X线程中信号量的使用方法详解 #### 前言 在多线程编程中,信号量(Semaphore)是一种常用的同步机制,用于限制可以同时访问某个资源或执行某个任务的线程数量。Python 的 `threading` 模块提供了 `...

    python使用信号量动态更新配置文件的操作

    Python中的信号量是一种同步机制,常用于多线程编程中控制对共享资源的访问,防止多个线程同时访问导致的数据不一致。然而,在这个场景中,信号量被用来处理操作系统发送的信号,如SIGHUP(挂断信号),而不是作为...

    Python for Signal Processing (Python 信号处理) 英文版

    本书名为《Python for Signal Processing》,作者是José Unpingco,是一本专注于使用Python语言进行信号处理的原版英文书籍。书中详细介绍了信号处理的基础知识,包括信号的时域分析和频域分析,并结合大量的实战...

    Desktop_python信号分组处理器_实验数据分组_电信号转换为位移信号_实验处理_

    在IT领域,尤其是在数据分析和信号处理中,"Desktop_python信号分组处理器_实验数据分组_电信号转换为位移信号_实验处理_"这个标题所涵盖的知识点涉及到多个关键环节。首先,我们要理解这是一个基于Python的桌面应用...

    【完整源码】基于信号量的多理发师问题实现

    (操作系统大作业的不错选择)主程序中可以输入椅子的数量、理发师的数量(可大于1)以及顾客流量(10~20),多个顾客线程和理发师线程应该能够正确的并发执行。程序应输出并发执行的过程,能够正确统计并显示每个...

    分布式锁与信号量分布式锁与信号量.txt

    - 许多编程语言(如Java、Python等)提供了信号量类库,使得开发者能够轻松地使用信号量。 **2.4 优缺点分析** - **优点**: - 简单易用,易于理解。 - 能够灵活控制资源访问的粒度。 - 在单机环境中效果显著。 ...

    第九周-第12章节-Python3.5-线程之信号量.avi

    第九周-第12章节-Python3.5-线程之信号量.avi

    分布式锁与信号量.md

    - 多数编程语言(如Java、C++、Python等)都有内置的信号量实现。 - 可以利用操作系统提供的原语实现信号量,例如POSIX线程库中的semaphore。 5. **注意事项**: - 需要考虑信号量的初始化问题,即如何合理设置...

    python红绿灯检测opencv识别红绿灯信号灯检测

    在本文中,我们将深入探讨如何使用Python和OpenCV库来实现红绿灯的检测与识别。这是一项在自动驾驶、交通监控以及智能交通系统中的关键技术,它涉及到计算机视觉、机器学习和人工智能领域。OpenCV(开源计算机视觉库...

Global site tag (gtag.js) - Google Analytics