Semaphore
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 is similar to Lock, but semaphore allows you to specify a maximum number of processes to access resources. Just as the resource has multiple doors, each door has a Lock. A process accesses resources, locks doors, and other doors can be used. But if all the doors are used, you have to wait for a process to release the Lock.
'''Semaphore''' import threading import time def run(n): semaphore.acquire() print("Thread:",n) time.sleep(1) semaphore.release() if __name__ == '__main__': #Set semaphore semaphore = threading.Semaphore(2)#Every 2 simultaneous execution for i in range(5): t = threading.Thread(target=run,args=(i,)) t.start()
Operation results:
Thread: 0 thread: 1 Thread: 2 thread: 3 Thread: 4 thread: 5 Thread: 6 thread: 7 Thread: 8 thread: 9
Conditional variable
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, wake up other threads through the notify method. Other threads in the wait state will re judge the conditions after receiving the wake-up. This process is repeated continuously to solve the complex synchronization problem.
'''Conditional variable''' import threading import time def run(n): con.acquire() print(f'Thread:{n}') con.notify()#Wake up other threads when starting this thread print(f'Thread:{n}Hang') con.wait()#Make it wait time.sleep(1) print(f'Thread:{n}Restart') con.notify() con.release() #Simultaneous operation if __name__ == '__main__': con = threading.Condition()#Conditional variable for i in range(10): t = threading.Thread(target=run,args=(i,)) t.start()
Thread: 0 Thread: 0 suspended Thread: 1 Thread: 1 suspended Thread: 0 started again Thread: 2 Thread: 2 suspended Thread: 3 Thread: 3 suspended Thread: 4 Thread: 4 suspended Thread: 5 Thread: 5 suspended Thread: 6 Thread: 6 pending Thread: 5 restart Thread: 8 Thread: 8 pending Thread: 9 Thread: 9 suspended Thread: 1 starts again Thread: 2 starts again Thread: 3 restart Thread 4: restart Thread: 7 Thread: 7 pending Thread: 6 restart Thread: 8 restart Thread: 9 starts again
Event
Python provides an event object for inter thread communication. It is a signal flag set by threads. If the signal flag bit is true, other threads wait until the signal contacts. Event objects can keep threads synchronized by notifying operations, and can realize thread synchronization operations in different processes.
The Event object implements a simple thread communication mechanism. It provides setting signal set(), clearing signal clear(), waiting for wait(), etc. to realize the communication between threads.
'''event''' import threading import time def car(): #Loop to detect if the event is set while True: if event.is_set():#If the event is set print('Trolley travel') else: print('Trolley stop') event.wait()#wait if the event is cleared def set_event(): #Loop, always let it set / cancel events while True: event.set()#Set event time.sleep(1) #In this 1 second, the 'trolley travel' will be printed repeatedly because thread car1 has been detecting event.clear() #Clear event time.sleep(1) #The printing will not be repeated within 1 second because thread car1 is wait ing #Then cycle to the beginning, the event continues to be set, and continue to print 'trolley travel' if __name__ == '__main__': event = threading.Event() #Thread start, two threads are started at the same time car1 = threading.Thread(target=car) car1.start() set1 = threading.Thread(target=set_event) set1.start()