互斥锁
- 互斥锁: 对共享数据进行锁定, 保证同一时刻只能有一个线程去操作.
- 互斥锁的注意点: 互斥锁是多个线程一起去抢, 抢到锁的线程先执行, 没有抢到锁的线程需要等待, 等互斥锁使用完释放后,其他等待的线程再去抢这个锁
- 互斥锁的使用: threading 模块中定义了 Lock 变量, 这个变量本质上是一个函数, 通过调用这个函数可以获取一把互斥锁
# 创建锁
mutex = threading.Lock()
# 上锁
mutex.acquire()
这里是同一时刻只有一个线程去操作的代码, 对共享的数据进行锁定
# 释放锁
mutex.release()
小黑板
- acquire 和 release 方法之间的代码同一时刻只能有一个线程去操作
- 如果在调用 acquire 方法的时候, 其他线程已经使用了这个互斥锁, 那么此时 acquire 方法会堵塞, 直到这个互斥锁释放后才能再次上诉.
- with: with 的作用就是自动给这个线程加上互斥锁,自动释放这个互斥锁
import threading
g_number = 0 # 全局变量多个线程可以读写,传递数据
def func(lock):
global g_number
# 尝试加锁
lock.acquire()
for i in range(1000000):
g_number += 1
# 释放锁
lock.release()
def func2(lock):
global g_number
# with 的作用相当于自动创建互斥锁, 自动释放互斥锁
with lock:
for i in range(1000000):
g_number += 1
def main():
# 1. 创建一个互斥锁
lock = threading.Lock()
# 2.创建一个子线程 让他修改全局变量
thd1 = threading.Thread(target=func1, args=(lock,))
thd2 = threading.Thread(target=func2, args=(lock,))
thd1.start()
thd2.start()
# 3. 主线程等待子线程退出 再去查看全局变量的结果
thd1.join()
thd2.join()
print("全局变量的值是 %d" g_number)
if __name__ = "__main__":
main()
# 提示: 加上互斥锁, 那么线程抢到这个锁我们决定不了, 那线程抢到那个线程先执行, 没有抢到的线程则需要等待
# 加上互斥锁多任务瞬间变成了单任务, 性能会下降, 也就是说同一时刻只能有一个线程去执行
# 控制台输出
全局变量的值是 20000000
小结:
- 互斥锁的作用就是保证同一时刻只能有一个线程去操作共享数据, 保证共享数据不会出现错误问题
- 使用互斥锁的好处就是确保某段代码只能由一个线程从头到尾地去执行
- 使用互斥锁会影响代码的执行效率, 多人改成了单任务执行
- 互斥锁如果没有使用好容易出现死锁的情况
- with 的作用就是自动给这个线程加上互斥锁,在自动释放互斥锁
来源:CSDN
作者:LanLanDeMing
链接:https://blog.csdn.net/LanlanDeming/article/details/103647637