[Python] How is the thread to be executed selected by the OS?

Discussão em 'Python' iniciado por Stack, Fevereiro 2, 2025.

  1. Stack

    Stack Membro Participativo

    import threading
    import time

    lock = threading.Lock()


    def high_priority():
    while True:
    with lock:
    print("High priority thread acquired lock")
    time.sleep(0.2)


    def low_priority():
    while True:
    with lock:
    print("Low priority thread acquired lock") # May never happen!
    time.sleep(0.1)


    t1 = threading.Thread(target=high_priority, daemon=True)
    t2 = threading.Thread(target=low_priority, daemon=True)

    t1.start()
    t2.start()

    time.sleep(1)


    I ran the code above 23 times before seeing low_priority get the lock.

    My aim is to understand what determines

    • when within the 1 second sleep of main script low_priority thread gets the lock
    • how often low_priority thread gets the lock

    However the experiments seem to require a long time so i'm looking for some theory first.

    Last 3 runs' output out of 23:

    ➜ deadlock python deadlock_priority.py
    High priority thread acquired lock
    High priority thread acquired lock
    High priority thread acquired lock
    High priority thread acquired lock
    High priority thread acquired lock
    ➜ deadlock python deadlock_priority.py
    High priority thread acquired lock
    High priority thread acquired lock
    High priority thread acquired lock
    High priority thread acquired lock
    High priority thread acquired lock
    ➜ deadlock python deadlock_priority.py
    High priority thread acquired lock
    High priority thread acquired lock
    High priority thread acquired lock
    Low priority thread acquired lock
    Low priority thread acquired lock
    Low priority thread acquired lock
    Low priority thread acquired lock


    Is priority determined by order of start method, or by length of sleep in the threads?

    t1.start()
    t2.start()


    I tried to sleep less on low_priority in hopes of giving it higher chance to take over, is this wishful thinking? I suspect time.sleep settings inside the lock context manager in both threads have no impact.

    Is there any way to make this experiment more reproducible? (meaning in a certain number of runs, i can see low_priority get the lock.

    What other parameters are interesting to tweak or add to the code to understand this or related issues better?

    I just wrote the code to study thread competition with no use case in mind, but intuition tells me there is some use. Can anyone explain if such patterns appear in meaningful code?

    I decided to randomly add sleeps outside the lock context manager and somehow low_priority gets the lock a lot more often?

    def high_priority():
    while True:
    time.sleep(0.0001)
    with lock:
    print("High priority thread acquired lock")
    time.sleep(0.2)


    def low_priority():
    while True:
    time.sleep(0.0001)
    with lock:
    print("Low priority thread acquired lock")
    time.sleep(0.1)


    Output of 1st 3 runs:

    ➜ deadlock python deadlock_sleep.py
    High priority thread acquired lock
    Low priority thread acquired lock
    High priority thread acquired lock
    Low priority thread acquired lock
    High priority thread acquired lock
    Low priority thread acquired lock
    High priority thread acquired lock
    ➜ deadlock python deadlock_sleep.py
    High priority thread acquired lock
    Low priority thread acquired lock
    High priority thread acquired lock
    Low priority thread acquired lock
    High priority thread acquired lock
    Low priority thread acquired lock
    High priority thread acquired lock
    ➜ deadlock python deadlock_sleep.py
    High priority thread acquired lock
    Low priority thread acquired lock
    High priority thread acquired lock
    Low priority thread acquired lock
    High priority thread acquired lock
    Low priority thread acquired lock
    High priority thread acquired lock

    Continue reading...

Compartilhe esta Página