pythonpython-multithreading

How to turn off a Thread with input() in it


I want to get an input from my console but I need my program to be alive.

Here's what I have, but when I want to turn the program off I need to type in the input:

import threading
import keyboard as kb

def turn_off():
    return kb.is_pressed('shift') and kb.is_pressed('1')

input_output = None

def Specjal_input():
    global input_output
    input_output = input('')

running = True
Input_Thread = threading.Thread(target=Specjal_input)
print("please enter a number")
Input_Thread.start()

while running:
    if turn_off():
        running = False
    else:
        if input_output is not None:
            running = False
        else:
            pass  # more program

if input_output is not None:
    print('\nentered number: {}'.format(input_output))
else:
    print("the program is turning off, input canseled")
Input_Thread.join()

I already tried using sys.exit() but it did not work


Solution

  • The issue with your code is that it doesn't handle the threading correctly and blocks the main thread while waiting for input. You want your program to continue running, able to handle input, but also to be terminated by a specific key press.

    Here's an improved version of your code that handles this by using non-blocking input with a separate thread:

    import threading
    import keyboard as kb
    import sys
    import time
    
    def turn_off():
        return kb.is_pressed('shift') and kb.is_pressed('1')
    
    
    input_output = None
    
    def specjal_input():
        global input_output
        input_output = input()
    
    running = True
    Input_Thread = threading.Thread(target=specjal_input)
    Input_Thread.daemon = True  # This ensures the thread will close when the main program ends
    Input_Thread.start()
    
    print("Please enter a number:")
    
    while running:
        if turn_off():
            running = False
            print("\nProgram is turning off...")
        elif input_output is not None:
            print('\nEntered number: {}'.format(input_output))
            running = False
        else:
            time.sleep(0.1)  # Just a small delay to avoid busy-waiting
    
    # The program will reach here when running is False
    Input_Thread.join(timeout=1)  # Wait for the thread to finish
    
    if input_output is None:
        print("The program is turning off, input canceled.")
    sys.exit()
    

    The Input_Thread is set as a daemon thread, meaning it will automatically close when the main program exits. This ensures that your program doesn't hang waiting for the thread to finish. Non-blocking Input: The main loop periodically checks if the user has entered anything. If input_output is None, it means no input has been provided yet, and the loop continues running. Graceful Exit: The join method with a timeout allows the input thread to be gracefully terminated if it hasn't completed yet when the main program is about to exit. The main loop continuously checks if the user has pressed the Shift + 1 keys to terminate the program, or if any input has been captured. If input is detected, the program prints it and exits. If the termination key combination is detected, the program exits without waiting for input. This approach allows your program to be responsive to both input and a termination command.