zoukankan      html  css  js  c++  java
  • Python 信号处理 signal 模块

    signal模块简介

    最近在看Linux signal 相关内容,signal可以被用来进程间通信和异步处理。Python标准库提供了signal包可以用来处理信号相关。这里讨论的是Unix系统中Python的signal模块。

    signal简单示例

    官方文档上有这样的示例:

    import signal, os
    
    # 定义一个信号处理函数,该函数打印收到的信号,然后raise IOError
    def handler(signum, frame):
        print 'Signal handler called with signal', signum
        raise IOError("Couldn't open device!")
    
    # 对SIGALRM(终止)设置处理的handler, 然后设置定时器,5秒后触发SIGALRM信号
    signal.signal(signal.SIGALRM, handler)
    signal.alarm(5)
    
    # This open() may hang indefinitely
    fd = os.open('/dev/ttyS0', os.O_RDWR)
    
    signal.alarm(0)          # 关闭定时器
    

    该示例实现的功能是,为了防止打开一个文件出错或者其他异常一直处于等待的状态,设定一个定时器,5秒后触发IOError。如果5s内正常打开文件,则清除定时器。

    signal说明

    基本的信号名

    import signal
    
    signal.SIGABORT
    signal.SIGHUP  # 连接挂断
    signal.SIGILL  # 非法指令
    signal.SIGINT  # 连接中断
    signal.SIGKILL # 终止进程(此信号不能被捕获或忽略)
    signal.SIGQUIT # 终端退出
    signal.SIGTERM # 终止
    signal.SIGALRM  # 超时警告
    signal.SIGCONT  # 继续执行暂停进程
    
    等等...
    

    常用信号处理函数

    • signal.signal(signalnum, handler)
      设置信号处理的函数
    • signal.alarm(time)
      设置发送SIGALRM信号的定时器
    • os.kill
      这个不属于signal模块,但其可以使用给某一进程发送信号

    signal使用示例

    示例1

    # From project httpscreenshot-master, under directory , in source file httpscreenshot.py.
    def timeoutFn(func, args=(), kwargs={}, timeout_duration=1, default=None):
        import signal
    
        class TimeoutError(Exception):
            pass
    
        def handler(signum, frame):
            raise TimeoutError()
    
        # set the timeout handler
        signal.signal(signal.SIGALRM, handler)
        signal.alarm(timeout_duration)
        try:
            result = func(*args, **kwargs)
        except TimeoutError as exc:
            result = default
        finally:
            signal.alarm(0)
            signal.signal(signal.SIGALRM, signal.SIG_DFL)
    
        return result
    

    上面这个示例实现了设置函数执行超时返回默认结果的功能。先是设置了一个超时处理函数,在函数中抛出自定义的抛出异常。在执行函数前设置了 signal.alarm ,当超出时间后触发抛出异常 SIGALRM, 然后捕获这个异常设置默认值,最后做下清理工作将定时器取消,并且将对 SIGALRM 的处理设为默认。

    示例2

    这个示例来源于这里。 需求是动态加载python导入的模块,也就是说,当导入的模块代码更新时,希望可以立即更新引用的代码。示例如下:

    # lib.py
    def scrape_me_bro():
            print "Scraping is fun"
    
    
    
    #scrape.py
    import time
    import signal
    import lib
    
    def scrape():
            # Assume we are hitting Streaming API
            # and doing something buzzwordy with it
            while True:
                    lib.scrape_me_bro()
                    time.sleep(2)
    
    def reload_libs(signum, frame):
            print "Received Signal: %s at frame: %s" % (signum, frame)
            print "Excuting a Lib Reload"
            reload(lib)
    
    # Register reload_libs to be called on restart
    signal.signal(signal.SIGHUP, reload_libs)
    
    # Main
    scrape()
    

    当运行scrape.py时,程序会每个两秒调用一次lib.py中的 scrape_me_bro() 方法,这时候如果lib.py里的方法变化了,向运行scrape.py的进程发送 SIGHUP 信号,那么它会重新加载lib.py,这样会接着循环执行修改后的 scrape_me_bro() 方法。

    参考资料

  • 相关阅读:
    练习与突破
    HTML input type=file文件选择表单的汇总(一)
    webpack学习之—— Configuration(配置)
    webpack学习之—— Plugins
    webpack学习之—— Loaders
    webpack学习之——Output
    webpack学习之——Entry Points(入口起点)
    CSS3 3D transform变换
    get和post请求的区别
    日期格式之——剩余时间(天,小时,分,秒)的计算方法
  • 原文地址:https://www.cnblogs.com/nisen/p/6071713.html
Copyright © 2011-2022 走看看