【问题标题】:Stopping a While loop when it ends a cycle in Python在 Python 中结束循环时停止 While 循环
【发布时间】:2018-06-28 15:00:24
【问题描述】:

这可能是一个奇怪的请求。我有一个无限的 While 循环,每个循环持续约 7 分钟,然后程序休眠几分钟让计算机冷却下来,然后重新开始。

看起来是这样的:

import time as t

t_cooling = 120
while True:
    try:
        #7 minutes of uninterrupted calculations here
        t.sleep(t_cooling)
    except KeyboardInterrupt:
        break

现在如果我想中断进程,我必须等到程序休眠 2 分钟,否则在运行周期中完成的所有计算都被浪费了。此外,计算涉及写入文件和使用multiprocessing,因此在计算阶段中断不仅是一种浪费,而且可能会损坏文件上的输出。

我想知道是否有办法向程序发出信号,表明当前循环是它必须执行的最后一个循环,这样就不会有在错误时刻中断的风险。要增加一个限制,它必须是一个通过命令行工作的解决方案。无法在运行程序的计算机上添加带有停止按钮的窗口。该机器具有基本的 Linux 安装,没有图形环境。计算机不是特别强大或新的,我需要尽可能多地使用 CPU 和 RAM。

希望一切都足够清楚。

【问题讨论】:

    标签: python-2.7


    【解决方案1】:

    不是很优雅,但很有效

    #!/usr/bin/env python
    import signal
    import time as t
    
    stop = False
    
    def signal_handler(signal, frame):
        print('You pressed Ctrl+C!')
        global stop
        stop = True
    
    signal.signal(signal.SIGINT, signal_handler)
    print('Press Ctrl+C')
    
    t_cooling = 1
    while not stop:
        t.sleep(t_cooling)
        print('Looping')
    

    【讨论】:

    • 这非常有效。以防万一有人对未来感兴趣,这不适用于subprocess 包,因为子处理程序也收到一个 CTRL+C 并且没有完成它的任务。我的解决方案是向另一个程序添加一个处理程序,只使用pass 作为指令。而且,这种解决方案不优雅是不正确的。我的最差。
    • @GRB,很高兴为您提供帮助。此外,要忽略信号,请使用:signal.signal(signal.SIGINT, signal.SIG_IGN)
    • @GRB,您可以更好地忽略子进程中的信号! stackoverflow.com/questions/5045771/…
    【解决方案2】:

    您可以使用单独的ThreadEvent 向主线程发出退出请求:

    import time
    import threading
    
    evt = threading.Event()
    
    def input_thread():
        while True:
            if input("") == "quit":
                evt.set()
                print("Exit requested")
                break
    
    threading.Thread(target=input_thread).start()
    
    t_cooling = 5
    while True:
        #7 minutes of uninterrupted calculations here
        print("starting calculation")
        time.sleep(5)
    
        if evt.is_set():
            print("exiting")
            break
    
        print("cooldown...")
        time.sleep(t_cooling)
    

    【讨论】:

    • 抱歉,这看起来不可行。程序会生成一些输出,所以这个解决方案在我的情况下并不实用,但我想在其他情况下也可以。
    【解决方案3】:

    为了完整起见,我在这里发布我的解决方案。它非常原始,但很有效。

    import time as t
    
    t_cooling = 120
    while True:
        #7 minutes of uninterrupted calculations here
        f = open('stop', 'r')
        stop = f.readline().strip()
        f.close()
        if stop == '0':
            t.sleep(t_cooling)
        else:
            break
    

    我只需要创建一个名为stop 的文件并在其中写入一个 0。当该 0 更改为其他值时,程序将在循环结束时停止。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-08-13
      • 1970-01-01
      • 2022-10-31
      • 2022-01-22
      • 2016-06-14
      • 1970-01-01
      • 2014-04-20
      • 2016-11-02
      相关资源
      最近更新 更多