Lock mechanism is a common thread synchronization mechanism whether you are java, C# or python. Compared with the lock mechanism of C#, python's locking mechanism is simpler. Calling the lock of threading standard library directly is enough. There are two functions in python's lock class, namely acquisition function and release function. The former plays the role of locking and sets the state to lock state, while the latter is locking function. Unlock and set the state to unlocked state. Let's look at the code:
# python Multithread Synchronization lock import threading from time import sleep num = 0 lock = threading.Lock() def func(st): global num print(threading.currentThread().getName() + ' try to acquire the lock') if lock.acquire(): # Modify the status to locked print(threading.currentThread().getName() + ' acquire the lock.') print(threading.currentThread().getName() + " :%s" % str(num)) num += 1 # sleep(st) print(threading.currentThread().getName() + ' release the lock.') lock.release() # Modify the status to unlocked t1 = threading.Thread(target=func, args=(8,)) t2 = threading.Thread(target=func, args=(4,)) t3 = threading.Thread(target=func, args=(2,)) t1.start() t2.start() t3.start()
We have three threads to call the same func function, because of the uncertainty of threads, if there is no lock, then the operation will be very confused, three threads to execute the same function, if the data changes involving variables are more pitfalls! So we add locks to ensure the correctness of data and the sequentiality of function execution.
The semaphore semaphore semaphore mechanism in python is also very simple to achieve thread synchronization. If you have a certain understanding of the operating system, you should be impressed with the operation of the PV primitive of the operating system. The semaphore class is a class under threading module. The main two functions are acquire function and release function, which are the same as those of lock class, but the function is different. The parameters of acquire function of semaphore mechanism are allowed. You set the maximum concurrency, that is to say, how many threads are allowed to operate on the same function or variable, and the execution decreases once, while the release function increases. If the count reaches 0, the thread is blocked and the method or variable is no longer allowed to be accessed by the thread.
# python Multithread Synchronization semaphore import threading # Initialization semaphore number...When called acquire Set the quantity to 0, Blocking threads wait for calls from other threads release() function semaphore = threading.Semaphore(2) def func(): if semaphore.acquire(): for i in range(5): print(threading.currentThread().getName() + ' get semaphore') semaphore.release() print(threading.currentThread().getName() + ' release semaphore') if __name__ == '__main__': for i in range(4): t1 = threading.Thread(target=func) t1.start()
We allow two threads to execute functions simultaneously at a time, as can be seen from the screenshot:
Event mechanism can not only realize the communication between threads, but also is a good way to achieve thread synchronization. Events are one of the simplest mechanisms for communication between threads. A thread indicates that an event and other threads are waiting for it.
event.py is a class under threading module. Compared with the previous two mechanisms, this class provides four methods: is_set(), set(), clear(), wait().
is_set determines whether the event management flag is true and will return only if true?
set sets the flag to true
clear sets the flag to flase
wait waits until the flag is true to stop blocking threads
import logging import threading import time # Print thread name and log information logging.basicConfig(level=logging.DEBUG, format="(%(threadName)-10s : %(message)s", ) def wait_for_event_timeout(e, t): """Wait t seconds and then timeout""" while not e.isSet(): logging.debug("wait_for_event_timeout starting") event_is_set = e.wait(t) # block, Waiting is set to true logging.debug("event set: %s" % event_is_set) if event_is_set: logging.debug("processing event") else: logging.debug("doing other work") e = threading.Event() # Initialization for false t2 = threading.Thread(name="nonblock", target=wait_for_event_timeout, args=(e, 2)) t2.start() logging.debug("Waiting before calling Event.set()") # time.sleep(7) e.set() # Wake up thread, Also will event Set to true logging.debug("Event is set")