One, about deadlocks.
Deadlock, that is, when multiple processes or threads in the process of execution, because of the contention for shared resources caused by a mutual waiting phenomenon, once the deadlock, without artificial processing, the program will continue to wait, which is also known as the deadlock process.
Here is an example of a "deadlock" phenomenon:
Import threading
Import time
LOCK_A = Threading. Lock ()
Lock_b = Threading. Lock ()
Class Test_thread (threading. Thread):
def __init__ (self):
Super (Test_thread,self). __init__ ()
def run (self):
SELF.FUN1 ()
Self.fun2 ()
def fun1 (self):
Lock_a.acquire ()
Print "I am%s, get res:%s---%s"% (Self.name, "ResA", Time.time ())
Lock_b.acquire ()
Print "I am%s, get res:%s---%s"% (Self.name, "Resb", Time.time ())
Lock_b.release ()
Lock_a.release ()
def fun2 (self):
Lock_b.acquire ()
Print ("I am%s, get res:%s---%s"% (Self.name, "Resb", Time.time ()))
Time.sleep (0.2)
Lock_a.acquire ()
Print ("I am%s, get res:%s---%s"% (Self.name, "ResA", Time.time ()))
Lock_a.release ()
Lock_b.release ()
if __name__ = = "__main__":
Print "Start---------------------------%s"% (Time.time ())
For I in range (0, 10):
My_thread = Test_thread ()
My_thread.start ()
Output execution Result:
Start---------------------------1494682814.1
I am Thread-1, get res:resa---1494682814.1
I am Thread-1, get res:resb---1494682814.1
I am Thread-1, get res:resb---1494682814.1
I am Thread-2, get res:resa---1494682814.1
The following is an analysis of the code, why a deadlock is generated:
Open 10 threads, first of all must have a thread to get lock_a this lock, the rest of the thread can only block, wait until Lock_a this lock is released, and then this thread got a lock is Lock_b, executed a print operation, release Lock_b this lock, at this time, Other threads still have no way to execute func1 inside resources, release Lock_b this lock, immediately after Lock_a also was released, at this time, the next thread can go to execute func1 in resources, next, thread 1 executed to Func2 got Lock_b this lock, Then execute a print output, I am Thread-1, get res: Resb---1494682814.1,sleep0.2 seconds, in the first thread sleep process the second thread to execute, the second thread in the execution of Func1, the first to get the lock_a this lock, executed the following print statement, I am Thread-2, get Res:resa---1494682814.1, the situation is that thread 1 got the Lock_b this lock, thread 2 got lock_a this lock, then the problem, thread 2 if you want to continue to execute func1 behind the content, Need to get Lock_b this lock, and at this time the Lock_b lock has been removed by thread 1 (thread 1 executed to the FUNC2 took the Lock_b lock, and has not been released ~), the thread 1,sleep0.2 seconds, need to continue to execute the contents of FUNC2, at this time, need to get lock _a Lock, (LOCK_A lock, by thread 2 execution func1 took, and not be released ~), now is the case of thread 1 need lock_a lock, but lock_a threads 2 in hand, thread 2 need lock_b lock, but Lock_b lock online 1 Hands ~ Both sides have no way to perform the release operation to the back.
This is the equivalent of two people to make a deal, a hand has an apple in the hands of pineapple, a want to eat the pineapple in the hand, B want to eat the apple in the hand, but who is not willing to first put their hands on the first thing to the other ~ so the program will always be stuck here.
This is how the deadlock is formed.
Second, the recursive lock.
There is a particularly effective way to solve the deadlock problem, which is recursive locking.
The biggest difference between a recursive lock and a normal mutex is that a lock of the object inside, maintained a counter, the initial value of this counter is 0, when a thread acquire once this lock, the internal counter +1, but this lock counter once more than 0, the other thread is unable to get this lock, Only when the front-line can be taken.
(The current thread acquire once, counter +1,release once counter-1, so, the current thread wants to completely release the recursive lock, acquire how many times, will release how many times!!! )
(This counter is the count in the recursive lock.) )
Take the example of the code that generated the deadlock in the earlier section:
Import threading
Import time
R_lock = Threading. Rlock () #RLock是用来产生递归锁的一个类, resulting in a recursive lock.
Class Test_thread (threading. Thread):
def __init__ (self):
Super (Test_thread,self). __init__ ()
def run (self):
SELF.FUN1 ()
Self.fun2 ()
def fun1 (self):
R_lock.acquire () #count +1
Print "I am%s, get res:%s---%s"% (Self.name, "ResA", Time.time ())
R_lock.acquire () #count再 +1
Print "I am%s, get res:%s---%s"% (Self.name, "Resb", Time.time ())
R_lock.release () #count-1
R_lock.release () #count again-1
def fun2 (self):
R_lock.acquire ()
Print ("I am%s, get res:%s---%s"% (Self.name, "Resb", Time.time ()))
Time.sleep (0.2)
R_lock.acquire ()
Print ("I am%s, get res:%s---%s"% (Self.name, "ResA", Time.time ()))
R_lock.release ()
R_lock.release ()
if __name__ = = "__main__":
Print "Start---------------------------%s"% (Time.time ())
R_lock = Threading. Rlock ()
For I in range (0, 10):
My_thread = Test_thread ()
My_thread.start ()
Output Result:
Start---------------------------1494687542.43
I am Thread-1, get res:resa---1494687542.43
I am Thread-1, get res:resb---1494687542.43
I am Thread-1, get res:resb---1494687542.43
I am Thread-1, get res:resa---1494687542.63
I am Thread-2, get res:resa---1494687542.63
I am Thread-2, get res:resb---1494687542.63
I am Thread-2, get res:resb---1494687542.63
I am Thread-2, get res:resa---1494687542.83
I am Thread-4, get res:resa---1494687542.83
I am Thread-4, get res:resb---1494687542.83
I am Thread-4, get res:resb---1494687542.83
I am Thread-4, get res:resa---1494687543.04
I am Thread-6, get res:resa---1494687543.04
I am Thread-6, get res:resb---1494687543.04
I am Thread-6, get res:resb---1494687543.04
I am Thread-6, get res:resa---1494687543.24
I am Thread-8, get res:resa---1494687543.24
I am Thread-8, get res:resb---1494687543.24
I am Thread-8, get res:resb---1494687543.24
I am Thread-8, get res:resa---1494687543.44
I am Thread-10, get res:resa---1494687543.44
I am Thread-10, get res:resb---1494687543.44
I am Thread-10, get res:resb---1494687543.44
I am Thread-10, get res:resa---1494687543.65
I am Thread-5, get res:resa---1494687543.65
I am Thread-5, get res:resb---1494687543.65
I am Thread-5, get res:resb---1494687543.65
I am Thread-5, get res:resa---1494687543.85
I am Thread-9, get res:resa---1494687543.85
I am Thread-9, get res:resb---1494687543.85
I am Thread-9, get res:resb---1494687543.85
I am Thread-9, get res:resa---1494687544.06
I am Thread-7, get res:resa---1494687544.06
I am Thread-7, get res:resb---1494687544.06
I am Thread-7, get res:resb---1494687544.06
I am Thread-7, get res:resa---1494687544.26
I am Thread-3, get res:resa---1494687544.26
I am Thread-3, get res:resb---1494687544.26
I am Thread-3, get res:resb---1494687544.26
I am Thread-3, get res:resa---1494687544.46
From the above example, the deadlock problem has been solved perfectly.
Finally, summarize the following recursive locks:
In Python, if the same thread needs to access the same shared resource multiple times, this time, you can use a recursive lock (Rlock), the inside of the recursive lock, maintain a lock object and a counter count variable, counter record the number of acquire, So that resources can be require multiple times. Until all the acquire of a thread are release, the other threads can get the resources.
So rlock can replace lock completely, can use recursive lock as far as possible with recursive lock!
This article is from the "Rebirth" blog, make sure to keep this source http://suhaozhi.blog.51cto.com/7272298/1925393
11.python Concurrency Entry (part4 deadlock and recursive lock)