catalogue
1. What are conditional variables?
1, Semaphore
1. What is a semaphore?
Semaphore is an abstract data type managed by the operating system, which is used to synchronize the use of shared resources in multiple threads. In essence, a semaphore is an internal data used to indicate how many concurrent reads can be made to the current shared resource.
2. How?
Semaphore class in threading module implements semaphore object, which can be used to control the number of threads obtaining resources. The acquire() and release() methods can be used as the context manager of the with statement. The acquire() method is called when entering, and release() is called when exiting.
#Semaphore import threading import time def run(n,x): semaphore.acquire() print(n) time.sleep(x) semaphore.release() if __name__ == '__main__': semaphore = threading.Semaphore(5)#Execute 5 threads simultaneously for i in range(16): t = threading.Thread(target=run,args=(i,i)) t.start()
2, Conditional variable
1. What are conditional variables?
The condition object provided by Python provides support for complex thread synchronization problems. Condition is called a condition variable. In addition to the acquire and release methods similar to Lock, it also provides wait and notify methods. The thread first acquires a condition variable and then judges some conditions. If the conditions are not met, wait; If the conditions are met, perform some processing. After changing the conditions, notify other threads through the notify method. Other threads in wait state will re judge the conditions after receiving the notification. This process is repeated continuously to solve the complex synchronization problem.
2. How?
The thread obtains the Condition object through acquire. When calling the wait method, the thread will release the lock inside the Condition and enter the blocked state. At the same time, the thread will be recorded in the waiting pool. When the notify method is called, the Condition object selects a thread from the waiting pool and tells it to call the acquire method to try to get the lock.
#Conditional variable import threading import time def run(x): # lock.acquire() con.acquire() print(f'thread {x}') con.notify() print(f'thread {x}Hang') con.wait() time.sleep(1) print(f'thread {x}Restart') con.notify() con.release() # lock.release() def run2(x): con.acquire() print(f'thread {x}') con.notify() print(f'thread {x}Hang') con.wait() time.sleep(1) print(f'thread {x}Restart') con.notify() con.release() if __name__ == '__main__': lock=threading.RLock() con=threading.Condition() # for i in range(10): # t = threading.Thread(target=run,args=(i,)) # t.start() t1=threading.Thread(target=run,args=(1,)) t1.start() t1=threading.Thread(target=run,args=(1,)) t1.start()
3, Events
1. What is an event?
Event is actually a simplified version of Condition. Event has no lock and cannot put the thread into synchronization blocking state.
How events work: initially, the signal flag in the Event object is set to false. If a thread waits for an Event object and the flag of the Event object is false, the thread will be blocked until the flag is true. If a thread sets the signal flag of an Event object to true, it will wake up all threads waiting for the Event object. If a thread waits for an Event object that has been set to true, it will ignore the Event and continue to execute.
2. How?
set(): set the flag to True and notify all threads in the waiting blocking state to resume running state.
clear(): set the flag to False.
wait(timeout): if the flag is True, it will be returned immediately. Otherwise, the thread will be blocked to the waiting blocking state and wait for other threads to call set().
isSet(): gets the built-in flag status and returns True or False.
#event import threading import time def car(): while True: if event.is_set(): print('Trolley travel') else: print('Trolley stop') event.wait() def set_event(): while True: event.set() time.sleep(1) event.clear() time.sleep(1) if __name__ == '__main__': event = threading.Event() car1 = threading.Thread(target=car) car1.start() set_e = threading.Thread(target=set_event()) set_e.start()