Mutex lock, deadlock and recursive lock, mutex lock Recursion

Source: Internet
Author: User

Mutex lock, deadlock and recursive lock, mutex lock Recursion
1. Mutex)

In the last section, we talked about thread security. Thread Synchronization ensures that multiple threads can securely access competing resources. The simplest synchronization mechanism is to introduce mutex locks. The mutex lock introduces a status for the resource: Locked/unlocked. When a thread wants to change the shared data, it first locks it. At this time, the resource status is "locked" and other threads cannot be changed until the thread releases resources, changes the resource status to "Unlocked", and other threads can lock the resource again. The mutex lock ensures that only one thread writes data at a time, thus ensuring data correctness in the case of multiple threads.

The threading module defines the Lock class to facilitate Lock handling:

# Create lock Lock = threading. lock () # lock. acquire (blocking = True, timeout =-1) # release Lock. release ()

Take the preceding example as an example:

# -*- coding: UTF-8 -*-import threadingclass MyThread(threading.Thread):    def run(self):        global n        lock.acquire()        n += 1        lock.release()        print(self.name + ' set n to ' + str(n))n = 0lock = threading.Lock()if __name__ == '__main__':    for i in range(5):        t = MyThread()        t.start()    print('final num: %d' % n)

Output:

Thread-1 set n to 1Thread-2 set n to 2Thread-3 set n to 3Thread-4 set n to 4Thread-5 set n to 5final num: 5

After locking, we can ensure that the data is correct.

Ii. deadlock

A deadlock occurs when a resource is called multiple times, but the caller fails to release the resource multiple times, causing mutual waiting. If no external force is applied, they will not be able to proceed. It is said that the system is in a deadlock state or the system has a deadlock.

2.1 A thread is locked multiple times but not released
Import threadingclass MyThread (threading. thread): def run (self): global n1, n2 lock. acquire () # Lock n1 + = 1 print (self. name + 'set n1 to '+ str (n1) lock. acquire () # Lock n2 + = n1 print (self. name + 'set n2 to '+ str (n2) lock. release () lock. release () n1, n2 = 0, 0 lock = threading. lock () if _ name _ = '_ main _': thread_list = [] for I in range (5): t = MyThread () t. start () thread_list.append (t) for t in thread_list: t. join () print ('final num: % d, % d' % (n1, n2 ))

Result:

Thread-1 set n1 to 1 # will keep waiting
Deadlock caused by mutual calls between more than 2.2 programs
import threading,time def run1():    print("grab the first part data")    lock.acquire()    global num    num +=1    lock.release()    return numdef run2():    print("grab the second part data")    lock.acquire()    global  num2    num2+=1    lock.release()    return num2def run3():    lock.acquire()    res = run1()    print('--------between run1 and run2-----')    res2 = run2()    lock.release()    print(res,res2)  if __name__ == '__main__':     num,num2 = 0,0    lock = threading.Lock()    for i in range(10):        t = threading.Thread(target=run3)        t.start() while threading.active_count() != 1:    print(threading.active_count())else:    print('----all threads done---')    print(num,num2) 
Iii. Recursive locks

The above two problems can be solved using the python recursive lock.

# Recursive lock rlock = threading. RLOCK ()

RLock internally maintains a Lock and a counter variable. counter records the number of acquire times so that resources can be require multiple times. Resources can be obtained only when all acquire of a thread is release. Here we take example 1. If you use RLock instead of Lock, no deadlock will occur:

  

#-*-Coding: UTF-8-*-import threadingclass MyThread (threading. thread): def run (self): global n1, n2 lock. acquire () # Lock n1 + = 1 print (self. name + 'set n1 to '+ str (n1) lock. acquire () # Lock n2 + = n1 print (self. name + 'set n2 to '+ str (n2) lock. release () lock. release () n1, n2 = 0, 0 lock = threading. RLock () if _ name _ = '_ main _': thread_list = [] for I in range (5): t = MyThread () t. start () thread_list.append (t) for t in thread_list: t. join () print ('final num: % d, % d' % (n1, n2 ))

Output:

Thread-1 set n1 to 1Thread-1 set n2 to 1Thread-2 set n1 to 2Thread-2 set n2 to 3Thread-3 set n1 to 3Thread-3 set n2 to 6Thread-4 set n1 to 4Thread-4 set n2 to 10Thread-5 set n1 to 5Thread-5 set n2 to 15final num:5 ,15

  

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.