当前位置:首页>python>Python基础篇 - 多线程-互斥锁

Python基础篇 - 多线程-互斥锁

  • 2026-10-11 08:15:27
Python基础篇 - 多线程-互斥锁
多线程-互斥锁

在之前的文章Python基础篇 - 多线程-线程的创建中,我们认识了多线程的创建;在Python基础篇 - 多线程-线程池中,我们学习了线程池的创建。

  我们知道多线程最大的特点就是:共享全局变量数据,而这个特点会导致线程的安全问题,会导致数据错乱、数据丢失、计算结果错误。想要解决线程争抢资源的问题,就得了解互斥锁。

一.多线程-数据安全问题

多线程会争抢资源,这会导致数据结果的错乱,如下面的代码演示:理论上计算,3个线程共累加15次,那这个程序执行完成后的结果是g_num=15,但是事实并非如此。

  这是因为在修改 g_num 前,有0.1秒的模拟时长,某个线程延时后,CPU立即分配计算资源给其他线程。此时0.1秒的休眠还未结束,这个线程还未将修改后的数据赋值给 g_num,因此其他线程获取到的并不是最新值,所以才出现上面的结果。

import timeimport threading# 定义任务函数def func():    global g_num # 修改全局变量    for _ in range(5):        t = g_num + 1        time.sleep(0.1)  # 模拟任务执行时长        g_num = t        print(f"{threading.current_thread().name}: {g_num}\n", end="")if __name__ == "__main__":    g_num = 0 # 全局变量    # 创建多线程-3个线程    threads = [threading.Thread(target=func, name=f"线程{i}") for i in range(3)]    # 多线程执行任务    [t.start() for t in threads]    [t.join() for t in threads]    print(g_num)  

二. 互斥锁

为了解决这个问题,当某个线程要更改共享数据时,先将其锁定,此时其他线程不能更改。直到该线程释放资源,其他的线程才能再次锁定该资源。互斥锁保证了同一时间只有一个线程进行操作,防止多个线程争抢资源,从而保证了多线程情况下数据的正确性。

  固定用法:

1.lock = threading.Lock(),创建锁

 2.lock.acquire() ,加锁(占用资源)

 3.lock.release() ,解锁(释放资源)

import timeimport threading# 任务函数def func():    global g_num    for _ in range(5):        lock.acquire()  # 获取锁        t = g_num + 1        time.sleep(0.1)        g_num = t        lock.release()  # 释放锁        print(f"{threading.current_thread().name}: {g_num}\n", end="")if __name__ == "__main__":    g_num = 0 # 全局变量    lock = threading.Lock()  # 创建锁    threads = [threading.Thread(target=func, name=f"线程{i}") for i in range(3)]    [t.start() for t in threads]    [t.join() for t in threads]    print(g_num)  # 15

这个程序执行完成之后,得到的是最终期望结果g_num=15。但是需要特别注意两个点。

  1. 上锁了,但是忘记了解锁:这会造成线程永久阻塞、程序卡死(死锁)。

  2. 锁加在循环外面的情况:所有代码一次性锁住,多线程直接变单线程,失去并发意义。当锁加循环外面,那只能等一个线程执行5遍任务,第二个线程才能进来执行任务,以此类推就是单线程任务。但是,锁加在循环里面,在一个线程执行任务耗时结束后,第二个线程就可以参与任务,不会导致一个线程循环跑5次的结果。

总结:今日我们学习了Python基础篇-多线程-互斥锁。由于多线程共享全局变量,多个线程同时修改数据会产生资源竞争,导致数据错乱丢失。我们使用threading.Lock创建互斥锁,通过上锁、解锁操作,保证同一时刻仅有一条线程修改共享数据,解决线程安全问题。加锁后程序由并行变为串行,牺牲运行速度换取数据准确性。在Python基础篇,后续我们将持续学习Python基础知识,介绍各种算法,祝每一位study er学习愉快。

合集链接
这里是我滴合集内容链接,大家感兴趣就康康吧。
1. 人工智能进阶之路 - 机器学习篇
2.人工智能进阶之路 - 深度学习篇
3. AI发展前点
4. 人工智能进阶之路-Python基础篇
5. 充电er的乱坠闲聊
6. Origin认知
点个 赞 你最好看

最新文章

随机文章