信号程序仅在准备就绪时退出

时间:2015-08-06 05:08:28

标签: python signals

  

重复How to prevent a block of code from being interrupted by KeyboardInterrupt in Python?

目的:

  • 程序收到信号时,只有在准备好后才会退出。

问题:

  • 期望的行为:
    • 信号在目标块期间到达。目标块完成后程序退出。
    • 信号到达目标区块之外。程序退出。
  • 目前的行为:
    • 信号在目标块期间到达。程序挂起。
    • 信号到达目标区块之外。程序退出。

我的设计的通用实现:

import threading, signal

def huphandler(signum, frame):
    with sig_lock:
        os._exit(0)

def loop():
    print 'in lock'
    time.sleep(5)

def idle_loop():
    while True:
        with sig_lock:
            t = multiprocessing.Process(target=loop)
            t.start()
            t.join()
        print 'out lock'
        time.sleep(5)

sig_lock = threading.Lock()
signal.signal(signal.SIGHUP, huphandler)
idle_loop()

2 个答案:

答案 0 :(得分:0)

如果你使用获得的锁杀死,那么你将程序置于死锁状态。

因为您刚刚杀死了持有锁的线程或子进程,所以它无法再释放它。然后你的主线程或任何其他线程将尝试获取锁,并阻塞直到锁可用。因此,以僵局结束。

答案 1 :(得分:0)

1.1。问题:

  • 信号处理程序将中断主线程,导致deadlock

1.2。解决方案:

  • 使用布尔值而不是锁定。

2.1。问题:

  • 当一个线程被中断时,它可能会停止运行中(即time.sleep),这是不稳定的。

2.2。解决方案:

  • 为了获得更高的稳定性,请将目标代码包装在子流程中。

提供所需结果的通用实施:

import threading, signal

def huphandler(signum, frame):
    print idle_loop.sig_lock
    if idle_loop.sig_lock:
        idle_loop.continuee = False
    else:
        print 'dont b here'
        os._exit(0)

def loop():
    print 'in lock'
    time.sleep(5)

def idle_loop():
    while True:
        idle_loop.sig_lock = True
        t = multiprocessing.Process(target=loop)
        t.start()
        t.join()
        print 'out lock'
        if idle_loop.continuee:
            idle_loop.sig_lock = False
            time.sleep(5)
        else: return


idle_loop.sig_lock = False
idle_loop.continuee = True
signal.signal(signal.SIGHUP, huphandler)
idle_loop()