0

I'm running a python script that is creating 5 threads on the windows OS. All of the threads are doing light work (api calls, simple computations)

However if I type on my keyboard, while the script is running, the letters appear with a very noticeable delay. My assumption: The OS keyboard event listener process and my python script process are sharing the same core and my threads are blocking the core therefore there is less time for other threads (like the key event listener).

I removed a single thread and with 4/5 threads everything works perfectly fine. However I need all 5 threads therefore I tried to also change the CPU affinity of my python script to only use one specific processor core.

p = psutil.Process()
p.cpu_affinity([1])

Now everything works fine however I'm not sure if there is a better solution...

Edit: Unfortunately I can't share the exact script however I tried to simplify the code but maintain it's meaning: There are two different message types a user can input (at any time) A and B. They are getting preprocessed and the final result gets appended to the corresponding messgage list. Another thread generates a response (in the mean time new messages could arrive to the reader thread that's why I chose multithreading). After the response is generate the message will be appended to list_C where another thread (response_execution) handles the execution of the response. The last thread is a (on_activate_h) is for precaution. Because I want to cancel the robot at any time with a certain key combination.

def reader():
    global list_A
    global list_B
    # checks constantly for inputs messages and evaluating the messages
    # preprocesses input messages reformatting, etc.
    # if message is okay append to list_A or list_B (depending on message type)


def response_generator():
    global list_A
    global list_B
    global list_C

    while True:
        if list_A:
            # if new message in list_A generate a corresponding response
            # api call involved takes sometimes some time.
            response = generate_response_A()
        if list_B:
            # if new message in list_B generate a corresponding response
            # api call involved takes sometimes some time.
            response = generate_response_B()
        # append final response to list_C
        list_C.append(response)


def response_execution():
    global list_C

    while True:
        if list_C:
            # api calls involved
            # execute the generated response
            pass


def on_activate_h():
    # cancel execution immediately
    robot.stop_execution()



input_thread = Thread(target=reader)
response_generator_thread = Thread(target=response_generator)
response_execution_thread = Thread(target=response_execution)
stop_robot_thread = keyboard.GlobalHotKeys({
    '<ctrl>+<alt>': on_activate_h})

input_thread.start()
response_generator_thread.start()
response_execution_thread.start()
stop_robot_thread.start()

input_thread.join()
response_generator_thread.join()
response_execution_thread.join()
stop_robot_thread.join()
Worker
  • 11
  • 4
  • 1
    it depends on what the code is doing, but why use 5 threads if there is nothing intensive ? please show a minimal reproducible example: https://stackoverflow.com/help/minimal-reproducible-example – D.L Jan 25 '23 at 17:04
  • 1
    Do your threads do `time.sleep` even with a very small delta? – Margaret Bloom Jan 25 '23 at 18:20
  • @MargaretBloom Yes, nearly every thread does at some point a time.sleep() with a delta ranging from 0.1 to 2 seconds. – Worker Jan 25 '23 at 18:57
  • 0.1 seconds is plenty long, a lot longer than a scheduler timeslice (often 10ms or 1ms). It would be not great if every running process had multiple threads that woke up 10x per second (instead of blocking on an event; being able to fully block waiting for an event is one reason to use a thread in the first place). But one inefficient program with 5 threads only waking up 10x per second won't slow down a computer to the point of interfering with keyboard input. That would be fine even on a single-core Pentium II or something. "very small delta" in this context would be under 10 microseconds – Peter Cordes Jan 25 '23 at 19:02

0 Answers0