有没有一种优雅的方法可以在 Python 中途停止一个长循环?

时间:2021-07-07 14:56:11

标签: python while-loop signals exit

我想做什么:

我拥有的是一个无限期运行的 python 脚本,直到用户决定停止它。理想情况下,我希望整个程序在用户提交 KeyboardInterrupt 时停止。然而,这只会导致程序立即跳到最后并继续重复。我已经尝试使用同步线程的替代解决方案,但它要么表现出两种行为:

  1. 执行与 KeyboardInterrupt 完全相同的操作。
  2. 在while循环结束后停止程序。

我在第二个困境中遇到的问题是我的 while 循环需要很长时间才能完成执行。是否有一种优雅的方法可以退出循环/脚本而无需等待其完成?比如,一旦用户提交 crtl+c 程序就退出?

我的尝试:

1.

thread_running = True

def function():

    while thread_running:

        # Do stuff that takes a long time

def termination():
    user_input = ''
    while user_input != 'e':
        user_input = input()

if __name__ == '__main__':
    print("\n*** Hit 'e' to exit.\n")

    t1 = Thread(target = function)
    t2 = Thread(target = termination)

    t1.start()
    t2.start()

    t2.join()
    thread_running = False
    print('\n*** Goodbye\n')
while True:

    try:

        # Execute long calculations

    except KeyboardInterrupt:
        raise
while True:

    try:

        # Execute long calculations

    except KeyboardInterrupt:
        break

3 的完整代码:

# Creates new temp log file
if os.path.exists('wp-logtemp.csv'):
    os.remove('wp-logtemp.csv')
os.mknod('wp-logtemp.csv')

while True:

    try:

        plan = 'userprof.jmx'

        # Run jmeter cli based on plan & output file
        os.system("./jmeter -n -t {} -l wp-logtemp.csv -J jmeterengine.force.system.exit=true".format(plan))

        # Array of elapsed times
        dataTime = []
        dataTime.clear()

        # Error counter
        err = 0

        # Open and read buffer
        with open('wp-logtemp.csv', 'r') as csvfile:

            reader = csv.reader(csvfile)
            # Skip header
            next(reader)

            for row in reader:
                # Converts from ms to s
                dataTime.append(float(row[1])/1000)
                if row[3] != '200':
                    err += 1

        # Sort times least to greatest
        dataTime.sort()

        # Sum all times
        timetot = sum(dataTime)

        # Number of rows
        requests = len(dataTime)

        # Calculate throughput (TP = number of requests / total time)
        through = requests / timetot
                    
        # Calculate average time (AV = total time / number of requests = 1/TP)
        timeavg = 1 / through

        # Calculate min
        timemin = (dataTime[0])

        # Calculate max
        timemax = (dataTime[len(dataTime)-1])

        # Intermidiary value for standev
        diff = sum(x - (timeavg**2) for x in dataTime)

        # Calculate standard deviation (s = sqrt((1/N-1)SUMOF(x-X)^2))
        standev = math.sqrt((1/(requests-1))*abs(diff))

        #Error % (false/total)
        erravg = float((err/requests)*100)

        print('**************')
        print('Number of requests = '+ str(requests))
        print('Total time = '+ str(timetot))
        print('Throughput = '+ str(through))
        print('Average time = '+ str(timeavg))
        print('Minimum time = '+ str(timemin))
        print('Maximum time = '+ str(timemax))
        print('Standard deviation = '+ str(standev))
        print('Error = '+ str(erravg))
        print('**************')

    except KeyboardInterrupt:
        break

1 个答案:

答案 0 :(得分:-2)

这对我有用:

import time
import threading
import sys

def check():
    while KeyboardInterrupt:
        try:
            break
            sys.exit(0)
        except:
            time.sleep(2)
threading.Thread(target=check).start()

def function():
    while True:
        # do stuff
function()

我添加了检查 KeyboardInterrupt 的函数,如果发生,它应该退出程序。

希望它会起作用;)