使用带有多线程的 input() 优雅地退出循环

问题描述 投票:0回答:1

我的程序中有一个函数,它是通过重复“count”次的 for 循环实现的。我需要能够随时通过在控制台中输入“stop”来中断循环。我使用两个线程实现了这一点 - 一个线程使用循环初始化该函数:

    def send_messages(count_msg: int, delay_msg: int):
        global stop_flag
        for _ in range(count_msg):
            if stop_flag:  # Boolean variable responsible for stopping the loop
                print('---Sending completed by the user [ОК]---')
                break
            message(messageText)  # Function responsible for sending a message
            time.sleep(delay_msg)
        if stop_flag:
            stop_flag = False  # Change the flag back so that the function can be called again

另一个线程初始化一个函数,通过 input() 等待用户输入。

    def monitor_input():
        global stop_flag 
        user_input = input()
        if user_input == 'stop':
            stop_flag = True  # Change the flag to stop the sending function


send_thread = threading.Thread(target=send_messages, args=my_args)
stop_thread = threading.Thread(target=monitor_input)
send_threading.start()
stop_threading.start()

一切正常,但有一个例外:如果循环没有被中断,只是等待其完成,则该函数仍然等待用户输入,并且不方便关闭程序,更准确地说,出现错误:

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte

我希望我能解决这个问题

我想解决这个问题,而不是为我自己,因为我已经找到了使用 msvcrt 模块的解决方案,但它仅适用于 Windows,我想找到一种更“灵活”的方法来做到这一点,因为我'我刚刚学习编程

我尝试通过错误处理来做到这一点:

    def monitor_input():
        global stop_flag
        try:
            user_input = input()
        except UnicodeDecodeError as e:
            user_input = ''
            print('Terminated by user [OK]')  
            sys.exit(1)
        if user_input == 'stop':
            stop_flag = True  # Change the flag to stop the sending function

这有效,但不是很好,因为程序必须关闭“两次”,也就是说,按下“终止”按钮后它不会终止。据我了解,这个问题是由于一个线程仍然处于活动状态所致。

我知道这是一个非常小的问题,但我想解决它并学习新的东西,所以我将非常感谢您的帮助!

python multithreading loops terminate
1个回答
0
投票

您可以使用 try- except 来处理 UnicodeDecodeError 并添加信号处理以更好地终止。

© www.soinside.com 2019 - 2024. All rights reserved.