线程互斥锁 Lock
前言
Python 线程互斥锁
1.创建互斥锁
# 导入线程threading模块
import threading
# 创建互斥锁
mutex = threading.Lock()
锁定资源/解锁资源
# 导入线程threading模块
import threading
# 声明全局变量
g_num = 0
# 创建互斥锁
mutex = threading.Lock()
def my_thread1():
# 声明全局变量
global g_num
# 循环 1000000 次,每次累计加 1
for i in range(0,1000000):
# 锁定资源
mutex.acquire()
g_num = g_num + 1
# 解锁资源
mutex.release()
def my_thread2():
# 声明全局变量
global g_num
# 循环 1000000 次,每次累计加 1
for i in range(0,1000000):
# 锁定资源
mutex.acquire()
g_num = g_num + 1
# 解锁资源
mutex.release()
def main(i):
# 声明全局变量
global g_num
# 初始化全局变量,初始值为 0
g_num = 0
# 创建两个线程,对全局变量进行累计加 1
t1 = threading.Thread(target=my_thread1)
t2 = threading.Thread(target=my_thread2)
# 启动线程
t1.start()
t2.start()
# 阻塞函数,等待线程结束
t1.join()
t2.join()
# 获取全局变量的值
print("第%d次计算结果:%d "% (i,g_num))
if __name__ == "__main__":
# 循环4次,调用main函数,计算全局变量的值
for i in range(1,5):
main(i)
'''
输出结果:
第1次计算结果:2000000
第2次计算结果:2000000
第3次计算结果:2000000
第4次计算结果:2000000
'''
注意:互斥锁一旦锁定之后要记得解锁,否则资源会一直处于锁定状态;
Python 线程死锁
1.引入库
1.单个互斥锁的死锁:acquire / release 是成对出现的,互斥锁对资源锁定之后就一定要解锁,否则资源会一直处于锁定状态,其他线程无法修改;任何一个线程没有释放资源 release,程序就会一直处于阻塞状态(在等待资源被释放)
2.多个互斥锁的死锁:在同时操作多个互斥锁的时候一定要格外小心,因为一不小心就容易进入死循环。
# 导入线程threading模块
import threading
# 导入线程time模块
import time
# 创建互斥锁
mutex_one = threading.Lock()
mutex_two = threading.Lock()
def programmer_thread1():
mutex_one.acquire()
print("我是程序员1,module1开发正式开始,谁也别动我的代码")
time.sleep(2)
# 此时会堵塞,因为这个mutex_two已经被线程programmer_thread2抢先上锁了,等待解锁
mutex_two.acquire()
print("等待程序员2通知我合并代码")
mutex_two.release()
mutex_one.release()
def programmer_thread2():
mutex_two.acquire()
print("我是程序员2,module2开发正式开始,谁也别动我的代码")
time.sleep(2)
# 此时会堵塞,因为这个mutex_one已经被线程programmer_thread1抢先上锁了,等待解锁
mutex_one.acquire()
print("等待程序员1通知我合并代码")
mutex_one.release()
mutex_two.release()
def main():
t1 = threading.Thread(target=programmer_thread1)
t2 = threading.Thread(target=programmer_thread2)
# 启动线程
t1.start()
t2.start()
# 阻塞函数,等待线程结束
t1.join()
t2.join()
# 整合代码结束
print("整合代码结束 ")
if __name__ == "__main__":
main()
'''
输出结果:
我是程序员1,module1开发正式开始,谁也别动我的代码
我是程序员2,module2开发正式开始,谁也别动我的代码
'''
分析:程序员 1 在等程序员 2 通知,程序员 2 在等程序员 1 通知,两个线程都陷入阻塞中,因为两个线程都在等待对方解锁,这就是死锁!所以在开发中对于死锁的问题还是需要多多注意!
重点总结
1.线程与线程之间共享全局变量需要设置互斥锁;
2.注意在互斥锁操作中 acquire / release 成对出现,并且保证上锁后一定要记得解锁,避免造成死锁;