This article mainly for you in detail the Python thread synchronization lock related data, with a certain reference value, interested in small partners can refer to
In the use of multi-threaded applications, how to ensure thread safety, as well as synchronization between threads, or access to shared variables and other issues is a very difficult problem, but also the use of multi-threaded problems, if not handled, will bring more serious consequences, using Python multi-threading to provide lock Rlock The Semaphore Event Condition is used to ensure synchronization between threads, which guarantees access to shared variables in mutually exclusive issues
Lock & Rlock: Mutex to ensure multi-threaded access to shared variables
Semaphore object: The enhanced version of the lock mutex can be owned by multiple threads at the same time, and lock can only be owned by one thread at a time.
Event object: It is a way of communicating between threads, which is equivalent to a signal that one thread can send a signal to another thread to perform operations.
Condition object: It can process data when certain events are triggered or when certain conditions are met
1. Lock (Mutual exclusion lock)
Request Lock-Enter lock pool wait-get lock-locked-release lock
Lock (Command Lock) is the lowest level of synchronization instruction available. When lock is locked, it is not owned by a particular thread. Lock contains two states-locking and non-locking, and two basic methods.
You can think of lock as having a lock pool, and when a thread requests a lock, the thread will be in the pool until it gets locked out of the pool. The threads in the pool are in a synchronous blocking state in the state diagram.
Construction Method:
Lock ()
Example method:
Acquire ([timeout]): Causes the thread to enter a synchronous blocking state, attempting to obtain a lock.
Release (): Releases the lock. The use of the front thread must have been locked or an exception will be thrown.
If Mutex.acquire (): Counter + = 1 print "I am%s, set counter:%s"% (self.name, counter) mutex.release ()
2, Rlock (can re-enter the lock)
A rlock (Reentrant lock) is a synchronous instruction that can be requested multiple times by the same thread. Rlock uses the concept of "owned threads" and "recursive hierarchy", while in a locked state, Rlock is owned by a thread. The thread that owns the Rlock can call acquire () again, releasing the lock at the same number of times that it needs to call release ().
It can be thought that Rlock contains a lock pool and a counter with an initial value of 0, each time the acquire ()/release () is successfully called, the counter is +1/-1, and the lock is unlocked for 0 o'clock.
Construction Method:
Rlock ()
Example method:
Acquire ([timeout])/release (): Similar to lock.
3. Semaphore (Shared object access)
Let's talk about semaphore, tell the truth semaphore is my latest use of the synchronization lock, similar to the implementation of the previous, I use the rlock to achieve, relatively some around, after all, Rlock is required to be locked and unlocked the "...
Semaphore manages a built-in counter,
Built-in counter whenever acquire () is called-1;
Built-in counter +1 when call Release ();
The counter cannot be less than 0, and when the counter is 0 o'clock, acquire () blocks the thread until another thread calls release ().
Directly on the code, we put semaphore control to 3, that is, there are 3 threads can use this lock, the rest of the thread is only blocking wait ...
#coding: Utf-8#blog xiaorui.ccimport timeimport threadingsemaphore = Threading. Semaphore (3) def func (): If Semaphore.acquire (): For I in range (3): time.sleep (1) print ( Threading.currentthread (). GetName () + ' get lock ') semaphore.release () print (Threading.currentthread (). GetName () + ' release lock ') for I in range (5): T1 = Threading. Thread (Target=func) T1.start ()
4. Event (inter-thread communication)
The event interior contains a flag bit that is initially false.
You can use Set () to set it to true;
or use Clear () to set it from new to false;
You can use Is_set () to check the status of the flag bit;
Another most important function is wait (timeout=none), which blocks the current thread until the internal flag bit of the event is set to TRUE or timeout expires. If the internal flag bit is true, the wait () function understands the return.
Import Threadingimport Timeclass MyThread (threading. Thread): Def __init__ (self, Signal): Threading. Thread.__init__ (self) self.singal = Signal def run (self): print "I am%s,i'll sleep ..."%self.name Self.singal.wait () print "I am%s, I awake ..."%self.nameif __name__ = = "__main__": Singal = Threading. Event () for T in range (0, 3): thread = MyThread (singal) Thread.Start () print "Main thread sleep 3 seconds ... "Time.sleep (3) Singal.set ()
5. Condition (thread synchronization)
Condition can be understood as a high-level lock, which provides more advanced functionality than locks, Rlock allows us to control complex thread synchronization issues. Threadiong. Condition maintains a trivial object internally (by default, Rlock), which can be passed in as a parameter when creating a Condigtion object. Condition also provides acquire, release method, its meaning and the acquire, release method consistent, in fact, it is simply a simple call inside the corresponding method of the object. Condition also provides the following methods (especially note: These methods can only be called after the acquire), otherwise the runtimeerror exception will be reported. ):
Condition.wait ([timeout]):
The Wait method releases the internal footprint, and the thread is suspended until the notification is woken up or timed out (if the timeout parameter is provided). The program will continue to execute when the thread is awakened and re-occupied.
Condition.notify ():
Wakes up a suspended thread (if there is a pending thread). Note: the Notify () method does not release the occupied locks.
Condition.notify_all ()
Condition.notifyall ()
Wakes all pending threads (if there are pending threads). Note: These methods do not release the locks that are occupied.
For condition There is an example, we can observe.
From threading import Thread, conditionimport timeimport randomqueue = []max_num = 10condition = Condition () class Producer Thread: def run (self): nums = Range (5) global queue while True: condition.acquire () if Len (queue) = = Max_num: print "Queue full, producer are Waiting" condition.wait () print "Space in queue, Consum Er notified the producer " num = Random.choice (nums) queue.append (num) print" produced ", Num Condition.notify () condition.release () time.sleep (Random.random ()) class Consumerthread (Thread): def run (self): global Queue and True: condition.acquire () if not queue: print ' Nothing ' in queue, Consumer is Waiting " condition.wait () print" Producer added something to queue and notified the consumer " num = Queue.pop (0) print "Consumed", num condition.notify () condition.release () time.sleep ( Random.random ()) Producerthread (). Start () Consumerthread (). Start ()