signal模块


1.简单测试(Windows XP平台)

def sigint_handler(signum, frame):
global is_signal_up
is_signal_up = True
print 'catched interrupt signal!'

import signal
signal.signal(signal.SIGINT, sigint_handler)

is_signal_up = False
while not is_signal_up:
pass
raw_input('hit to quit...')

==>Assertion OK!

2.交互测试(Windows XP平台)

def sigint_handler(signum, frame):
global is_sigint_up
is_sigint_up = True
print 'catched interrupt signal!'

import signal
signal.signal(signal.SIGINT, sigint_handler)

is_sigint_up = False
while not is_sigint_up:
line = raw_input()
if line=='quit':
  break
  
==>Assertion Failed!
场景: while循环等待用户输入, 当按下中断键产生中断信号,
sigint_handler并没有像我们所想象的那样被调用!

分析: 在Python Library Reference中, 关于signal模块有这样
一段statement: When a signal arrives during an I/O operation,
it is possible that the I/O operation raises an exception after
the signal handler returns. This is dependent on the underlying
Unix system's semantics regarding interrupted system calls.
即: 如果在I/O操作的时候信号产生了, 有一种情况是可能的:在信号
被处理前, I/O操作抛出了异常. 这依赖于低层Unix系统中断系统调用
语意.

我们可以延伸一下:I/O操作对中断信号的默认处理是抛出异常, 但你
同时为该信号注册了相应的处理器, 那么在中断信号到来时, 确定的
处理方法取决于异常抛出和信号处理器的优先级别, 这与系统实现有
关, 或者抛出异常, 或者调用处理器, 或者二者都被实行, 只是先后
顺序有别.


3.整后重测(考虑平台可移植性)

core_data = None
def real_handler():
global core_data
# todo: some operation on core_data

def sigint_handler(signum, frame):
real_handler()
global is_sigint_up
is_sigint_up = True
print 'catched interrupt signal!'
import signal
signal.signal(signal.SIGINT, sigint_handler)
is_sigint_up = False
while not is_sigint_up:
try:
  line = raw_input()
  if line=='quit':
   break
except KeyboardInterrupt:
  real_handler()
  print 'catched KeyboardInterrupt exception'