Python: Realize keyboard input monitoring during program running by opening a new thread to monitor events

The previous article introduced two methods for Python programs to monitor keyboard input in Windows systems, namely keyboard and pynput toolkit, but both methods will encounter problems when remotely controlling Linux servers: Python: Monitoring in Windows
systems Two methods of keyboard input

This article introduces the method of monitoring events by opening a new thread to realize keyboard input monitoring during program running. This method can also be used normally when controlling a Linux server remotely.


First, to define a thread that can actively control its end, you need to inherit the Thread class in threading and rewrite its _stop method:

import threading

class StoppableThread(threading.Thread):
    """
    a stoppable thread, inherit from threading.Thread
    """
    def __init__(self, target):
        super(StoppableThread, self).__init__(target=target)

    def _stop(self):
        """
        stop the thread, overwrite method, modified from threading.py
        :return:
        """

        lock = self._tstate_lock
        self._is_stopped = True
        self._tstate_lock = None
        if not self.daemon:
            with threading._shutdown_locks_lock:
                threading._shutdown_locks.discard(lock)

Note here that the Python version is at least 3.7. If you use Python 3.6, an error will be reported that the threading module does not have the _shutdown_locks_lock attribute:
Python 3.6 error

Define an event, and write the target function of the thread according to the event:

# event
event_flag = threading.Event()
event_flag.set()

def thread_target():
    """
    thread target function, inspect event flag
    :return:
    """

    global event_flag

    while True:
        if event_flag.is_set():
            input("Press <enter> to pause:")
            event_flag.clear()
        event_flag.wait()

To verify the effect, the main thread is timed through the for loop, and the new thread monitors keyboard input:

import time

if __name__ == '__main__':
    # thread
    thread = StoppableThread(target=thread_target)
    thread.start()

    tms = time.time()
    for i in range(100):
        print(i)
        time.sleep(0.1)

        if not event_flag.is_set():
            s = input("Please input something:")
            print("You input {}".format(s))
            event_flag.set()
    tme = time.time()
    tm = round(tme - tms, 3)
    print()
    print("for loop running time:  {} s".format(tm))

    thread._stop()

Guess you like

Origin blog.csdn.net/Zhang_0702_China/article/details/124285831