python暂停命令_Python:捕获Ctrl-C命令。提示“确实要退出(y / n)”,如果没有,请恢复执行...

1586010002-jmsa.png

I have a program that may have a lengthy execution. In the main module I have the following:

import signal

def run_program()

...time consuming execution...

def Exit_gracefully(signal, frame):

... log exiting information ...

... close any open files ...

sys.exit(0)

if __name__ == '__main__':

signal.signal(signal.SIGINT, Exit_gracefully)

run_program()

This works fine, but I'd like the possibility to pause execution upon catching SIGINT, prompting the user if they would really like to quit, and resuming where I left off in run_program() if they decide they don't want to quit.

The only way I can think of doing this is running the program in a separate thread, keeping the main thread waiting on it and ready to catch SIGINT. If the user wants to quit the main thread can do cleanup and kill the child thread.

Is there a simpler way?

解决方案

The python signal handlers do not seem to be real signal handlers; that is they happen after the fact, in the normal flow and after the C handler has already returned. Thus you'd try to put your quit logic within the signal handler. As the signal handler runs in the main thread, it will block execution there too.

Something like this seems to work nicely.

import signal

import time

import sys

def run_program():

while True:

time.sleep(1)

print("a")

def exit_gracefully(signum, frame):

# restore the original signal handler as otherwise evil things will happen

# in raw_input when CTRL+C is pressed, and our signal handler is not re-entrant

signal.signal(signal.SIGINT, original_sigint)

try:

if raw_input("\nReally quit? (y/n)> ").lower().startswith('y'):

sys.exit(1)

except KeyboardInterrupt:

print("Ok ok, quitting")

sys.exit(1)

# restore the exit gracefully handler here

signal.signal(signal.SIGINT, exit_gracefully)

if __name__ == '__main__':

# store the original SIGINT handler

original_sigint = signal.getsignal(signal.SIGINT)

signal.signal(signal.SIGINT, exit_gracefully)

run_program()

The code restores the original signal handler for the duration of raw_input; raw_input itself is not re-entrable, and re-entering it

will lead to RuntimeError: can't re-enter readline being raised from time.sleep which is something we don't want as it is harder to catch than KeyboardInterrupt. Rather, we let 2 consecutive Ctrl-C's to raise KeyboardInterrupt.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值