互斥锁LOCK()与RLOCK()

Posted zuzhuangmengxiang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了互斥锁LOCK()与RLOCK()相关的知识,希望对你有一定的参考价值。

资源总是有限的,程序运行如果对同一个对象进行操作,则有可能造成资源竞争,也可能导致读写混乱,此时需要引入锁。

锁提供如下方法: 
1.Lock.acquire([blocking])    # 上锁
2.Lock.release()      # 解锁
3.threading.Lock()      # 加载线程的锁对象,是一个基本的锁对象,一次只能一个锁定,其余锁请求,需等待锁释放后才能获取

4.threading.RLock() 多重锁,在同一线程中可用被多次acquire。如果使用RLock,那么acquire和release必须成对出现, 
调用了n次acquire锁请求,则必须调用n次的release才能在线程中释放锁对象

例如: 
无锁:

 1 import threading
 2 import time
 3 
 4 g_num = 0
 5 
 6 
 7 def work1(num):
 8     for i in range(num):
 9         global g_num
10         g_num += 1
11     print("___in work1,g_num is %d" % g_num)
12 
13 
14 def work2(num):
15     for i in range(num):
16         global g_num
17         g_num += 1
18     print("___in work2,g_num is %d" % g_num)
19 
20 
21 t1 = threading.Thread(target=work1, args=(1000000,))
22 t2 = threading.Thread(target=work2, args=(1000000,))
23 t1.start()
24 t2.start()
25 
26 time.sleep(3)
27 
28 print("___g_num is %d" % g_num)

  运行结果:

1 ___in work1,g_num is 1194618
2 ___in work2,g_num is 1334899
3 ___g_num is 1334899

引入锁:

 1 import threading
 2 import time
 3 
 4 # 定义一个全局变量
 5 g_num = 0
 6 
 7 
 8 def work1(num):
 9     global g_num
10     for i in range(num):
11         # 互斥锁上锁和解锁间包含的代码越少越好
12         mutex.acquire()
13         g_num += 1
14         mutex.release()
15     print("___in work1,g_num is %d" % g_num)
16 
17 
18 def work2(num):
19     global g_num
20     for i in range(num):
21         mutex.acquire()
22         g_num += 1
23         mutex.release()
24     print("___in work2,g_num is %d" % g_num)
25 
26 
27 # 创建一个互斥锁,默认是没有上锁的
28 mutex = threading.Lock()
29 
30 
31 t1 = threading.Thread(target=work1, args=(1000000,))
32 t2 = threading.Thread(target=work2, args=(1000000,))
33 t1.start()
34 t2.start()
35 
36 time.sleep(3)
37 
38 print("___g_num is %d" % g_num)

  运行结果:

1 ___in work1,g_num is 1945701
2 ___in work2,g_num is 2000000
3 ___g_num is 2000000

其中: 
  lock=threading.Lock()加载锁的方法也可以换成lock=threading.RLock()

  如果将上面的work1改为:

1 mutex.acquire()
2 global g_num
3 mutexk.acquire()
4     for i in range(num):
5         g_num += 1
6         mutex.release()
7         print("___in work1,g_num is %d" % g_num)
8         mutexk.release()

  那么: 
  lock=threading.Lock() 加载的锁,则一直处于等待中,锁等待 
  而lock=threading.RLock() 运行正常

lock()避免死锁的解决方法:

  1.程序设置时要尽量避免(银行家算法)

  2.添加超时时间

以上是关于互斥锁LOCK()与RLOCK()的主要内容,如果未能解决你的问题,请参考以下文章

Lock()与RLock()锁

python 归纳 (二四)_多进程数据共享和同步_锁Lock&RLock

互斥锁 & 共享锁

ReentrantReadWriteLock场景应用

递归锁,死锁,使用递归锁解决死锁,信号量

并发编程---死锁||递归锁---信号量---Event事件---定时器