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即信号编号( 数字),例如:

      

      Python 2.7.9 (default, Dec 10 2014, 12:24:55) [MSC v.1500 32 bit (Intel)] on win32
      Type "copyright", "credits" or "license()" for more information.
      >>> import signal
      >>> signal.SIGINT
      2
      >>> 

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

    ==================================================================

    接收信号:signal.signal(sig,action)

    官方文档:
    signal.signal(signalnum, handler)

    Set the handler for signal signalnum to the function handler. handler can be a callable Python object taking two arguments (see below), or one of the special values signal.SIG_IGN or signal.SIG_DFL. The previous signal handler will be returned (see the description of getsignal() above). (See the Unix man page signal(2).)

    When threads are enabled, this function can only be called from the main thread; attempting to call it from other threads will cause a ValueError exception to be raised.

    The handler is called with two arguments: the signal number and the current stack frame (None or a frame object; for a description of frame objects, see the description in the type hierarchy or see the attribute descriptions in the inspect module).

    On Windows, signal() can only be called with SIGABRT, SIGFPE, SIGILL, SIGINT, SIGSEGV, or SIGTERM. A ValueError will be raised in any other case.

    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)

    >>> import os
    >>> help(os.kill)
    Help on built-in function kill in module nt:
    
    kill(...)
        kill(pid, sig)
        
        Kill a process with a signal.
    
    >>> 

    pid为进程号, sig为信号

    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()

    官方文档:

    signal.pause()

    Cause the process to sleep until a signal is received; the appropriate handler will then be called. Returns nothing. Not on Windows. (See the Unix man page signal(2).)

    等待直到接收一个信号

    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)

    官方文档:
    signal.alarm(time)

    If time is non-zero, this function requests that a SIGALRM signal be sent to the process in time seconds. Any previously scheduled alarm is canceled (only one alarm can be scheduled at any time). The returned value is then the number of seconds before any previously set alarm was to have been delivered. If time is zero, no alarm is scheduled, and any scheduled alarm is canceled. If the return value is zero, no alarm is currently scheduled. (See the Unix man page alarm(2).) Availability: Unix.

    如果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()

    ================================================================

  • 相关阅读:
    Linux-RedHat 手动创建RAID和LVM分区
    Centos 文件系统 xfs、ext4、ext3 的区别
    CentOS7.5 rpm方式安装MySQL8.0.13
    virtualbox-host-only模式主机能上网虚拟机无法上网的问题解决
    RPA-智能流程自动化解决方案
    论文笔记——Rethinking the Inception Architecture for Computer Vision
    论文笔记——Factorized Convolutional Neural Networks
    论文笔记—Flattened convolution neural networks for feedforward acceleration
    论文笔记——Data-free Parameter Pruning for Deep Neural Networks
    AlexNet网络结构特点总结
  • 原文地址:https://www.cnblogs.com/xautxuqiang/p/5339602.html
Copyright © 2011-2022 走看看