zoukankan      html  css  js  c++  java
  • python模块之signal信号

    简介

    作用:发送和接收异步系统信号

      信号是一个操作系统特性,它提供了一个途径可以通知程序发生了一个事件并异步处理这个事件。信号可以由系统本身生成,也可以从一个进程发送到另一个进程。

    由于信号会中断程序的正常控制流,如果在中间接收到信号,有些操作(特别是I/O操作)可能会发生错误。

    接收信号

      signal.signal(sig,action)

      sig为某个信号,action为该信号的处理函数

      例如:

        signal.signal(signal.SIGALRM, hanlder)       hanlder为信号处理函数

    windows下sig信号:

    >>> dir(signal)
      ['CTRL_BREAK_EVENT', 'CTRL_C_EVENT', 'NSIG', 'SIGABRT', 'SIGBREAK', 'SIGFPE',
       'SIGILL', 'SIGINT', 'SIGSEGV', 'SIGTERM', 'SIG_DFL', 'SIG_IGN', '__doc__', '__name__', '__package__', 
      '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']
    

    即通过建立一个回调函数来接收信号,这个回调函数称为信号处理函数(signal hanlder),它会在信号出现时调用。

     信号处理函数包括信号编号及被信号中断那一时刻的栈帧。

      def hanlder(signum, frame):
    
          something...
    

      signum即信号编号( 数字),例如:

    >>> import signal
    >>> signal.SIGINT
      2
    

      frame为被信号中断那一时刻的栈帧。

    接收信号

    signal.signal(sig,action)

    import signal
    import os
    import time
    
    def receive_signal(signum, stack):
        print 'Received:', signum
    
    # 注册信号处理程序
    signal.signal(signal.SIGUSR1, receive_signal)
    signal.signal(signal.SIGUSR2, receive_signal)
    
    # 打印这个进程的PID方便使用kill传递信号
    
    print 'My PID is:', os.getpid()
    
    # 等待信号,有信号发生时则调用信号处理程序
    while True:
        print 'Waiting...'
        time.sleep(3)
    

    SIGUSR1和SIGUSR2是留给用户使用的信号。windows下无这两个信号。

    这个脚本会无限循环,每次暂停3秒钟。有信号到来时,sleep()调用被中断,信号处理程序receive_signal被调用.信号处理程序返回时,循环继续。

    发送信号

    os.kill(pid, sig):pid为进程号, sig为信号

    >>> import os
    >>> help(os.kill)
    Help on built-in function kill in module nt:
    
    kill(...)
        kill(pid, sig)
        
        Kill a process with a signal.
    
    >>> 
    
    import os
    import signal
    import time
    
    def signal_usr1(signum, frame):
        "Callback invoked when a signal is received"
        pid = os.getpid()
        print 'Received USR1 in process %s' % pid
    
    print 'Forking...'
    child_pid = os.fork()
    if child_pid:
        print 'PARENT: Pausing before sending signal...'
        time.sleep(1)
        print 'PARENT: Signaling %s' % child_pid
        os.kill(child_pid, signal.SIGUSR1)
    else:
        print 'CHILD: Setting up a signal handler'
        signal.signal(signal.SIGUSR1, signal_usr1)
        print 'CHILD: Pausing to wait for signal'
        time.sleep(5)
    

    父进程使用kill()和signal模块向子进程发送信号。在父进程中,使用kill()发送一个USR1信号之前会暂停很短一段时间,这个短暂的暂停使子进程有时间建立信号处理程序。

    signal.pause():等待直到接收一个信号

    import signal
    import os 
    import time
    
    def do_exit(sig, stack):
        raise SystemExit('Exiting')
    
    # 将SIGINT的默认处理程序替换为SIG_IGN
    signal.signal(signal.SIGINT, signal.SIG_IGN)
    signal.signal(signal.SIGUSR1, do_exit)
    
    print 'My PID:', os.getpid()
    
    signal.pause()
    

    正常情况下,SIGINT会产生一个KeyboardInterrupt,这个例子将忽略SIGINT,并在发现SIGUSR1时产生一个SystemExit。

    signal.alarm(time):如果time是非0,这个函数则响应一个SIGALRM信号并在time秒后发送到该进程。

    import signal
    import time
    
    def received_alarm(signum, stack):
        print 'Alarm:', time.ctime()
    
    # Call receive_alarm in seconds
    signal.signal(signal.SIGALRM, received_alarm)
    signal.alarm(2)
    
    print 'Before:', time.ctime()
    time.sleep(4)
    print 'After:', time.ctime()
    

      

  • 相关阅读:
    在软硬件系统总体架构设计
    WCF服务重构
    步步为营 .NET 设计模式学习笔记 四、Singleton(单例模式)
    我爱编程
    对.NET初学者两个问题的个人见解
    郁闷的一本书《深入解析Windows操作系统》
    欢迎使用 PDF.NET 数据开发框架【转载】
    使用ASP.NET MVC2+PDF.NET 构建一个简单的新闻管理程序
    不使用DalFactory和IDAL,支持多种数据库应用
    Web开发人员非常有用的手册
  • 原文地址:https://www.cnblogs.com/wangshuyang/p/9233993.html
Copyright © 2011-2022 走看看