简体   繁体   中英

alternating inputs in two threads

import threading
import time
def Tommy():
    i=0
    while True:
        lock.acquire()
        combine = input('Tommy:')
        lock.release()
        time.sleep(0.5)
        i=i+1
        if combine == 'q':
            break
def Cherry():
    i=0
    while True:
        lock.acquire()
        combine = input('Cherry:')
        lock.release()
        time.sleep(0.5)
        i=i+1
        if combine == 'q':
            break
lock = threading.Lock()
thread1 = threading.Thread(target=Tommy)
thread2 = threading.Thread(target=Cherry)
thread1.start()
thread2.start()

May I know why this code is so smart that it can alternately call Tommy and Cherry, so that they never talk to themselves? I think it is because of acquiring lock, but I have no idea why it can do so.

From Python documentation:

When more than one thread is blocked in acquire() waiting for the state to turn to unlocked, only one thread proceeds when a release() call resets the state to unlocked; which one of the waiting threads proceeds is not defined, and may vary across implementations.

It means that any other thread can't enter the lock block of code, it any other thread have already entered the block and have not released lock yet.

lock does not prevent other code blocks (not locked) to process in other threads.

import threading
import time


def notifier():
    # Not blocked by the lock
    while True:
        time.sleep(5)
        print("Notify")


def tommy(lock: threading.Lock):
    i = 0
    while True:
        # prevent other threads from performing operations when lock is blocked by another thread
        with lock:
            combine = input('Tommy:')
        time.sleep(0.5)
        i += 1
        if combine == 'q':
            break


def cherry(lock: threading.Lock):
    i = 0
    # prevent other threads from performing operations when lock is blocked by another thread
    while True:
        with lock:
            combine = input('Cherry:')
        time.sleep(0.5)
        i += 1
        if combine == 'q':
            break


if __name__ == '__main__':
    _lock = threading.Lock()
    thread1 = threading.Thread(target=tommy, args=(_lock, ))
    thread2 = threading.Thread(target=cherry, args=(_lock, ))
    notify_th = threading.Thread(target=notifier, daemon=True)
    notify_th.start()
    thread1.start()
    thread2.start()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM