进程_线程 之(三) --- 线程安全

本文探讨了在多线程环境下,线程安全问题的产生原因及解决方案,通过实例演示了线程冲突现象,并介绍了线程同步和互斥锁的使用方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

线程安全

  • 无问题时
 1 import threading
 2 
 3 m = 0
 4 # 如果多个线程去操作同一个外部资源,那么就可能造成线程的不安全。
 5 # 多个线程同时访问同一个外部资源,就可能会出现读写冲突
 6 def increase():
 7     global m
 8     for i in range(100): # 循环次数少,不会出现问题
 9         m += 1
10     print(m)
11 
12 # 线程冲突
13 def conflict():
14     # 创建5个线程,这5个线程同时的去操作外部的m变量
15     for _ in range(5):
16         t = threading.Thread(target=increase)
17         t.start()
18     # 现在是5个线程同时在访问m,当所有的线程都开启以后,操作系统会将他们放入一个轮询队列中去并发执行(每个线程分配一个时间片)。
19     # 当循环次数较少(执行这个线程用的时间越少),使用的时间不足以超出时间片,如果时间过长(即耗时任务)就会超出时间片,就会进而让出cpu
20 
21 
22 if __name__ == '__main__':
23     conflict()
1 运行结果:
2 """
3   100
4   200
5   300
6   400
7   500
8 """
  • 出现线程冲突
 1 import threading
 2 
 3 m = 0
 4 # 如果多个线程去操作同一个外部资源,完成这个任务所花的时间远远超出线程的时间片。此线程还没有完成对此外部资源的操作,其他资源就来操作了,那么就可能造成线程的不安全。
 5 # 多个线程同时访问同一个外部资源,就可能会会出现读写冲突
 6 def increase():
 7     global m
 8     for i in range(1000000): # 循环次数多,出现问题
 9         m += 1
10     print(m)
11 
12 # 线程冲突
13 def conflict():
14     # 创建5个线程,这5个线程同时的去操作外部的m变量
15     for _ in range(5):
16         t = threading.Thread(target=increase)
17         t.start()
18     # 现在是5个线程同时在访问m,当所有的线程都开启以后,操作系统会将他们放入一个轮询队列中去并发执行(每个线程分配一个时间片)。
19     # 当循环次数较少(执行这个线程用的时间越少),使用的时间不足以超出时间片,如果时间过长(即耗时任务)就会超出时间片,就会进而让出cpu
20 
21 
22 if __name__ == '__main__':
23     conflict()
 1 运行结果:
 2 """
 3 1554797
 4 1765071
 5 1850168
 6 1916170
 7 2079668
 8 """
 9 
10 # ------------------- 运行结果出现错误-----------------------

解决办法

  • 使用线程同步

 1 import threading
 2 
 3 m = 0
 4 # 如果多个线程去操作同一个外部资源,那么就可能造成线程的不安全。
 5 # 多个线程同时访问同一个外部资源,就可能会会出现读写冲突
 6 def increase():
 7     global m
 8     for i in range(1000000): # 循环次数少,不会出现问题
 9         m += 1
10     print(m)
11 # 加入线程同步来解决线程冲突
12 def threadSync():
13     for _ in range(5):
14         t = threading.Thread(target=increase)
15         t.start()
16         # 将线程加入同步对列。。但线程同步会造成线程的阻塞
17         t.join() # 同步就是串行,将所有的任务加入到同一个同步队列中,前面的任务不执行完后面的不能开启
18 
19 if __name__ == '__main__':
20 
21     threadSync()
  • 给资源加互斥锁 [只有读或只有写操作加互斥锁]
 1 import threading
 2 
 3 m = 0
 4 lock = threading.Lock()  # 创建一个互斥锁,不会造成线程阻塞问题
 5 def increase2():
 6     global m
 7     if lock.acquire(): # 获取互斥锁,并作出判断
 8         for i in range(1000000):
 9             m += 1
10         print(m)
11     lock.release()  # 使用完毕以后解除互斥锁
12     print("我是线程:",threading.current_thread().name)
13 
14 def threadLock():
15     for _ in range(5):
16         t = threading.Thread(target=increase2)
17         t.start()
18 
19 if __name__ == '__main__':
20     threadLock()
21 
22 # -------------- 正常输出结果 ---------------

 

转载于:https://www.cnblogs.com/TMMM/p/11379090.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值