快速理解线程锁

时间:2021-05-21 17:59:20

线程锁

线程锁真的好麻烦啊!!!

找了几篇博客发现写的都不一样 相关联内容太多不容易理解

所以现在需要理清

  • 什么是线程锁
  • 应用场景
  • 怎么用
  • 优缺点

1. 什么是线程锁机制

多线程可以同时运行多个任务

但是当多个线程同时访问共享数据时,可能导致数据不同步,甚至错误!

so,不使用线程锁, 可能导致错误

啰嗦两句: 比如你在银行取钱的同时你女朋友用支付宝取钱 不同线程同时访问同一资源 如果资源不加锁可能会导致银行亏本 卡里有100却取出200这种错误

2. 应用场景

I/O密集型操作 需要资源保持同步

3.用法

#锁的使用
#创建锁
lock = threading.Lock()
#锁定
lock.acquire([timeout])
#释放
lock.release()

example

import  threading   
import  time   

counter = 0 
counter_lock = threading.Lock() #只是定义一个锁,并不是给资源加锁,你可以定义多个锁,像下两行代码,当你需要占用这个资源时,任何一个锁都可以锁这个资源 
counter_lock2 = threading.Lock()  
counter_lock3 = threading.Lock() 

#可以使用上边三个锁的任何一个来锁定资源 

class MyThread(threading.Thread):#使用类定义thread,继承threading.Thread 
     def __init__(self,name):   
        threading.Thread.__init__(self)   
        self.name = "Thread-" + str(name) 
     def run(self):   #run函数必须实现 
         global counter,counter_lock #多线程是共享资源的,使用全局变量 
         time.sleep(1);   
         if counter_lock.acquire(): #当需要独占counter资源时,必须先锁定,这个锁可以是任意的一个锁,可以使用上边定义的3个锁中的任意一个 
            counter += 1    
            print "I am %s, set counter:%s"  % (self.name,counter)   
            counter_lock.release() #使用完counter资源必须要将这个锁打开,让其他线程使用 

if  __name__ ==  "__main__":   
    for i in xrange(1,101):   
        my_thread = MyThread(i) 
        my_thread.start()

4.优缺点

优点:保证资源同步
缺点:有等待肯定会慢

5.扩展(死锁与递归锁)

如果多个线程要调用多个对象,而A线程调用A锁占用了A对象,B线程调用了B锁占用了B对象,A线程不能调用B对象,B线程不能调用A对象,于是一直等待。这就造成了线程“死锁”。

Threading模块中,也有一个类,RLock,称之为可重入锁。该锁对象内部维护着一个Lock和一个counter对象。counter对象记录了acquire的次数,使得资源可以被多次require。最后,当所有RLock被release后,其他线程才能获取资源。在同一个线程中,RLock.acquire可以被多次调用,利用该特性,可以解决部分死锁问题。

就是把 lock=threading.Lock()改成lock = threading.RLock()