递归锁
一把大锁在加一把小锁。
import threading
import 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.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)
过程分享:
1、启动10个线程,每个线程都执行run3。
2、run3中先加了一个锁,然后执行run1。
3、run1中也加了一个锁,计算完成后解锁返回数据。执行run2。
4、run2中同样加了一个锁,计算完成后解锁打印run1,run2返回值。
5、最后打印num1、num2。
需要注意的是在执行过程中是有两把锁的,一个run3,一个run1或者run2。
运行结果:
11
11
11
11
11
11
11
11
# 程序进入死循环
死循环的原因是解锁的时候 钥匙拿错了导致进程退不出来,解决死锁就是要使用递归锁。
threading.Lock() 改为 threading.RLock()
import threading
import 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(1):
t = threading.Thread(target=run3)
t.start() while threading.active_count() != 1:
print(threading.active_count())
else:
print('----all threads done---')
print(num, num2)
运行结果
grab the first part data
--------between run1 and run2-----
grab the second part data
1 1
----all threads done---
1 1
实现原理:
解锁的时候找对应的钥匙。
信号量
互斥锁 同时只允许一个线程更改数据,而Semaphore是同时允许一定数量的线程更改数据 ,比如厕所有3个坑,那最多只允许3个人上厕所,后面的人只能等里面有人出来了才能再进去。简单的说就是互斥锁同一时间只能要一个线程修改数据,信号量同一时间可以让多个线程修改数据。信号量可以挂多吧锁。
import threading,time def run(n):
semaphore.acquire()
time.sleep(1)
print("run the thread: %s\n" %n)
semaphore.release() if __name__ == '__main__': num= 0
semaphore = threading.BoundedSemaphore(5) #最多允许5个线程同时运行
for i in range(20):
t = threading.Thread(target=run,args=(i,))
t.start() while threading.active_count() != 1:
pass #print threading.active_count()
else:
print('----all threads done---')
print(num)
每一个进程结束了就重新添加一个新的进去。