11.python Concurrency Entry (part4 deadlock and recursive lock)

Source: Internet
Author: User

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)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.