Python 如何在不结束代码且不使用 KeyboardInterrupt 的情况下手动结束正在收集数据的无限 while 循环?

Python how can I manually end an infinite while loop that's collecting data, without ending the code and not using KeyboardInterrupt?

在我的代码中,我有一个 "while True:" 循环,在收集实时数据(3-5 小时)时需要 运行 不同的时间。由于时间没有预先确定,我需要在不终止脚本的情况下手动结束 while 循环,以便它可以继续执行脚本中的下一段代码。

我不想在循环结束时使用"input()",因为每次循环结束时我都必须手动告诉它继续循环,我正在收集实时数据到一半第二,所以这不实用。

我也不想使用键盘中断,遇到了问题。还有其他解决方案吗?我只看到 try/except 和 "keyboardinterrupt"

def datacollect()
def datacypher()

while True:
    #Insert code that collects data here
    datacollect()

#end the while loop and continue on
#this is where i need help

datacypher()
print('Yay it worked, thanks for the help')

我希望手动结束循环,然后继续编写对收集到的数据起作用的代码。

如果您需要更多详细信息或对我的措辞有疑问,请告诉我。我之前只问过一个问题。我在学习。

一个选项,您可以查找文件是否存在,例如:

import os.path

fname = '/tmp/stop_loop'

def datacollect()
def datacypher()

while not os.path.isfile(fname):
    #Insert code that collects data here
    datacollect()

#end the while loop and continue on
#this is where i need help

datacypher()
print('Yay it worked, thanks for the help')

如果该文件不存在,它将继续执行 while 循环。然后,当您想停止 while 循环时,只需执行 touch /tmp/stop_loop 即可停止 while 循环。

我怀疑 isfile() 应该是相当有效的,所以也许这不会太糟糕。

在第二个线程中添加一个关键侦听器如何?按 Enter 后,您将通过共享布尔手动将脚本移动到下一阶段。第二个线程不应该减慢进程,因为它在 input().

上阻塞
from threading import Thread
from time import sleep

done = False

def listen_for_enter_key_press():
    global done
    input()
    done = True

listener = Thread(target=listen_for_enter_key_press)
listener.start()

while not done:
    print('working..')
    sleep(1)

listener.join()

print('Yay it worked, thanks for the help')

中断循环的一种方法是使用信号。

import signal

def handler(signum, stackframe):
    global DONE
    DONE = True

signal.signal(signal.SIGUSR1, handler)

DONE = False
while not DONE:
    datacollect()

datacypher()

循环将继续,直到您的程序接收到 USR1 信号(从 shell 发送,例如,通过 kill -s USR1 <pid>,其中 <pid> 是您程序的进程 ID),在下一次循环测试其值时 DONE 将是 True

您可以通过安装 handler 作为 signal.SIGINT 的处理程序而不是 signal.SIGUSR1 来适应键盘中断,因为默认的信号处理程序会引发 KeyboardInterrupt 例外。