python信号处理函数 python数字信号处理( 四 )


复制代码代码如下:
while 1:
alive = False
for i in range(cc):
alive = alive or threads[i].isAlive()
if not alive:
break
这样修改后,程序完全按照预想运行了:可以顺利的打印每个线程应该打印的所有数字,也可以中途用Ctrl+C终结整个进程 。完整的代码如下:
复制代码代码如下:
#!/bin/env python
# -*- coding: utf-8 -*-
#filename: peartest.py
import threading, signal
is_exit = False
def doStress(i, cc):
global is_exit
idx = i
while not is_exit:
if (idx10000000):
print "thread[%d]: idx=%d"%(i, idx)
idx = idx + cc
else:
break
if is_exit:
print "receive a signal to exit, thread[%d] stop."%i
else:
print "thread[%d] complete."%i
def handler(signum, frame):
global is_exit
is_exit = True
print "receive a signal %d, is_exit = %d"%(signum, is_exit)
if __name__ == "__main__":
signal.signal(signal.SIGINT, handler)
signal.signal(signal.SIGTERM, handler)
cc = 5
threads = []
for i in range(cc):
t = threading.Thread(target=doStress, args=(i,cc))
t.setDaemon(True)
threads.append(t)
t.start()
while 1:
alive = False
for i in range(cc):
alive = alive or threads[i].isAlive()
if not alive:
break
其实 , 如果用python写一个服务,也需要这样,因为负责服务的那个线程是永远在那里接收请求的,不会退出,而如果你想用Ctrl+C杀死整个服务,跟上面的压力测试程序是一个道理 。总结一下 , python多线程中要响应Ctrl+C的信号以杀死整个进程,需要:
1.把所有子线程设为Daemon;
2.使用isAlive()函数判断所有子线程是否完成,而不是在主线程中用join()函数等待完成;
3.写一个响应Ctrl+C信号的函数,修改全局变量,使得各子线程能够检测到,并正常退出 。
如何使用python处理心音信号在了解了Linux的信号基础之 后,Python标准库中的signal包就很容易学习和理解 。signal包负责在Python程序内部处理信号,典型的操作包括预设信号处理函数,暂 停并等待信号,以及定时发出SIGALRM等 。要注意 , signal包主要是针对UNIX平台(比如Linux, MAC OS),而Windows内核中由于对信号机制的支持不充分,所以在Windows上的Python不能发挥信号系统的功能 。
信号(signal)-- 进程之间通讯的方式,是一种软件中断 。一个进程一旦接收到信号就会打断原来的程序执行流程来处理信号 。
定义信号名
signal包定义了各个信号名及其对应的整数 , 比如:
import signal
print(signal.SIGABRT)
print(signal.SIG_DFL)
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()函数来传递的 。

推荐阅读