代码之家  ›  专栏  ›  技术社区  ›  unutbu

在SIGINT之后保存工作

  •  4
  • unutbu  · 技术社区  · 15 年前

    我有一个程序需要很长时间才能完成。我想要 SIGINT (ctrl-c)并调用 self.save_work() 方法。

    signal_hander() 从那以后就不起作用了 self signal_handler() .

    self.save_work 在一个小时后被叫来 信号 ?

    #!/usr/bin/env python
    import signal 
    
    def signal_handler(signal, frame):    
        self.save_work()   # Does not work
        exit(1)
    signal.signal(signal.SIGINT, signal_handler)
    
    class Main(object):
        def do_stuff(self):
            ...
        def save_work(self):
            ...
        def __init__(self):
            self.do_stuff()
            self.save_work()
    
    if __name__=='__main__':
        Main()
    
    3 回复  |  直到 15 年前
        1
  •  4
  •   Nadia Alramli    15 年前

    如果你只想抓住ctr+c,那么你可以抓住 KeyboardInterrupt 例外情况:

    class Main(object):
        def do_stuff(self):
            ...
        def save_work(self):
            ...
        def __init__(self):
            try:
                self.do_stuff()
            except KeyboardInterrupt:
                pass # Or print helpful info
            self.save_work()
    

    我并不认为这是一个好的设计。看起来您需要使用函数而不是构造函数。

        2
  •  3
  •   Udi    12 年前

    通常,“工作”涉及某种大循环。要驯服循环并防止它在未知步骤中中断,可以使用以下上下文管理器:

    import signal
    
    class GracefulInterruptHandler(object):
    
        def __init__(self, sig=signal.SIGINT):
            self.sig = sig
    
        def __enter__(self):
    
            self.interrupted = False
            self.released = False
    
            self.original_handler = signal.getsignal(self.sig)
    
            def handler(signum, frame):
                self.release()
                self.interrupted = True
    
            signal.signal(self.sig, handler)
    
            return self
    
        def __exit__(self, type, value, tb):
            self.release()
    
        def release(self):
    
            if self.released:
                return False
    
            signal.signal(self.sig, self.original_handler)
    
            self.released = True
    
            return True
    

    使用:

    import time
    
    /// do stuff:
    with GracefulInterruptHandler() as h:
        for i in xrange(1000):
            print "..."
            time.sleep(1)
            if h.interrupted:
                print "interrupted!"
                time.sleep(5)
                break
    
    save_work()
    

    从这里开始: https://gist.github.com/2907502

        3
  •  2
  •   jldupont    12 年前
    import signal
    
    def signal_handler(signal, frame):    
       #do some stuff
    
    def main():
       #do some more stuff
    
    
    if __name__=='__main__':
        signal.signal(signal.SIGINT, signal_handler)
        main()