Semaphores, in other words, control the number of concurrent threads, which is the number of concurrent threads in turn
See the example:
import threading # Import module import time # Import module class Exam(threading.Thread): # Create class def __init__(self, num): # initialization super(Exam, self).__init__() # Parent class initialization self.num = num # initialize variable def run(self): # Override parent method semaphore.acquire() # Semaphore acquisition print(self.num) # Print time.sleep(2) # Delay 2 seconds semaphore.release() # Release semaphore if __name__ == "__main__": # Main function semaphore = threading.Semaphore(3) # Create an instance and set the semaphore to 3 for i in range(50): # 50 cycles exam = Exam(60) # Create instance exam.start() # Open thread
Output results:
We found that after setting the semaphore, it is a group of every three, that is, after three threads, and then the next three
Condition variable:
Condition variables are usually associated with a Lock. When you need to share a Lock among multiple contidions, you can pass a Lock/RLock instance to the constructor, otherwise it will generate an RLock instance itself. It can be understood that in addition to the Lock pool with Lock, condition also includes a wait pool. The threads in the pool are in the wait blocking state in the state diagram until another thread calls notify() to notify subsequent threads. After receiving the notification, the thread enters the Lock pool to wait for locking, That is, the running of one thread can accommodate another thread to run halfway from the first run
import threading # Import module import time # Import module class Test(threading.Thread): # Create class def __init__(self, num): # initialization super(Test, self).__init__() # Parent class initialization self.num = num # initialize variable def run(self): # Override parent method con.acquire() # Acquire lock print("Thread:" + self.num) # Print con.notify() # Notify subsequent threads print("thread " + self.num + "Hang") # Print con.wait() # The thread hangs until it times out or receives a notify notification time.sleep(2) # Delay 2 seconds print("thread " + self.num + "Restart") # Print con.notify() # Notify subsequent threads con.release() # Release lock class Test2(threading.Thread): def __init__(self, num2): super(Test2, self).__init__() self.num2 = num2 def run(self): con.acquire() # Acquire lock print("Thread:" + self.num2) # Print con.notify() # Notify subsequent threads print("thread " + self.num2 + "Hang") # Print con.wait() # The thread hangs until it times out or receives a notify notification time.sleep(2) # Delay 2 seconds print("thread " + self.num2 + "Restart") # Print con.notify() # Notify subsequent threads con.release() # Release lock if __name__ == "__main__": # Main function con = threading.Condition() # Create a conditional variable instance t1 = Test(str(1)) # Create instance t1.start() # Open thread t2 = Test2(str(2)) # Create instance t2.start() # Open thread
Output results
It can be seen that after thread 1 is started, thread 2 will be notified to start, then thread 1 will hang, then thread 2 will start, then thread 1 will be notified, then thread 2 will hang, then thread 1 will start again, and then thread 2 will be notified to start again. This is the operation principle of condition variables.
event:
import threading # Import module import time # Import module class Test(threading.Thread): # Create class def __init__(self): # initialization super(Test, self).__init__() # Parent class initialization # self.num = num # initialize variable def run(self): # Override parent method while True: # Infinite loop if event.is_set(): # Determine whether to set events print("Event trigger") # Print else: # negative print("Event stop") # Print event.wait() # Wait for the event to stop for 3 seconds class Test2(threading.Thread): # Create class def __init__(self, ): # initialization super(Test2, self).__init__() # Parent class initialization # self.num2 = num2 def run(self): # Rewrite classification method while True: # Infinite loop event.set() # Set event time.sleep(1) # Delay 1 second event.clear() # Clear event time.sleep(3) # Delay 3 seconds if __name__ == "__main__": # Main function event = threading.Event() # Create time instance t1 = Test() # Create instance t1.start() # Open thread t2 = Test2() # Create instance t2.start() # Open thread
Output results:
In the interval, when the if judges that the setting event is detected, it will print "event trigger" and then delay for one second, but the program will also detect whether the event still exists. When the delay occurs, the event does exist, so it will print all the time. When the event is cleared (clear method), the program detects that the event is cleared, so it will print "event stop" and delay for 3 seconds, Ordered programs are infinite loops, so they continue to recreate events, cycle over and over, and continue the whole repeated process.