线程锁(互斥锁)和递归锁
在多线程编程中,引入了互斥锁的概念,用于保证线程中共享数据操作的完整性。它用来保证在任一时刻,只能有一个线程访问该对象。
在python中,使用threading模块提供的Lock类,通过来下面的例子来演示互斥锁的使用方法。
1 import threading 2 import time 3 counter = 0 4 mutex = threading.Lock()#申请一把锁 5 class MyThread(threading.Thread): 6 def __init__(self): 7 threading.Thread.__init__(self) 8 def run(self): 9 global counter, mutex #声明两个参数为全局变量 10 time.sleep(1); 11 if mutex.acquire():#上锁 12 counter += 1 13 print("I am %s, set counter:%s" % (self.name, counter)) 14 mutex.release() #释放锁 15 if __name__ == "__main__": 16 for i in range(0, 10): 17 my_thread = MyThread() 18 my_thread.start()
输出结果如下:
1 I am Thread-3, set counter:1 2 I am Thread-2, set counter:2 3 I am Thread-1, set counter:3 4 I am Thread-4, set counter:4 5 I am Thread-10, set counter:5 6 I am Thread-6, set counter:6 7 I am Thread-7, set counter:7 8 I am Thread-5, set counter:8 9 I am Thread-9, set counter:9 10 I am Thread-8, set counter:10
同步阻塞
当一个线程调用Lock对象的acquire()方法获得锁时,这把锁就进入“locked”状态。因为每次只有一个线程可以获得锁,所以如果此时另一个线程试图获得这个锁,
该线程就会变为同步阻塞状态。直到拥有锁的线程调用锁的release()方法释放锁之后,该锁进入“unlocked”状态。线程调度程序从处于同步阻塞的线程中选择一个来获得锁,
并使得该线程进入运行(running)状态。
递归锁
如果碰到锁嵌套怎么办,这个嵌套是指当我一个线程在获取临界资源时,又需要再次获取。此时会造成程序挂起,即死锁。
在python中为了支持在同一线程中多次请求同一资源,python提供了可重入锁RLock内部维护着一个Lock和一个counter变量,counter记录了acquire的次数,从而使得资源可以被多次
require。直到一个线程所有的acquire都被release,其他线程才能获取资源。
通过例子来说明递归锁的使用方法
import threading, time
def run1():
print("grab the first part data")
lock.acquire()
global num
num += 1
lock.release()
return num
def run2():
print("grab the second part data")
lock.acquire()
global num2
num2 += 1
lock.release()
return num2
def 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.RLock()
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)
事事有回音
凡事有交代
件件有着落

浙公网安备 33010602011771号