当前位置: 首页 > news >正文

【多线程】竞态条件是什么?

【多线程】竞态条件是什么?

本文来自于我关于多线程系列文章。欢迎阅读、点评与交流
1.【多线程】互斥锁(Mutex)是什么?
2.【多线程】临界区(Critical Section)是什么?
3.【多线程】计算机领域中的各种锁
4.【多线程】信号量(Semaphore)是什么?
5.【多线程】信号量(Semaphore)常见的应用场景
6.【多线程】条件变量(Condition Variable)是什么?
7.【多线程】监视器(Monitor)是什么?
8.【多线程】什么是原子操作(Atomic Operation)?
9.【多线程】竞态条件是什么?

竞态条件 是指一个系统或进程的输出,依赖于不受控制的事件发生的顺序或时机。当多个线程/进程同时访问和操作共享数据时,最终的执行结果取决于它们执行的精确顺序,而这个顺序是无法预测的,从而导致不可预知的行为。


一个生动的比喻:银行转账

假设你的银行账户里有 100元。你同时做了两件事:

  1. 操作A(存款):在你的手机APP上,点击存入 50元。
  2. 操作B(取款):在ATM上,点击取出 50元。

这两个操作几乎在同一时刻发生,相当于两个“线程”在同时处理你的账户余额。

正常的、正确的流程应该是(互斥的):

· 线程A:读取余额(100) → 计算新余额(100 + 50 = 150) → 写入新余额(150)
· 线程B:读取余额(150) → 计算新余额(150 - 50 = 100) → 写入新余额(100)
· 最终结果: 余额为 100元,正确。

但在竞态条件下,可能会发生这样的错误流程:

  1. 时刻1:线程A读取余额,得到 100。
  2. 时刻2:在线程A计算和写入新余额之前,线程B也读取了余额,它读到的也是 100。
  3. 时刻3:线程A计算 100 + 50 = 150,并写入新余额 150。
  4. 时刻4:线程B计算 100 - 50 = 50,并写入新余额 50。
  5. 最终结果:你的账户余额变成了 50元。你存的钱“消失”了!

问题出在哪?
出在“读取-计算-写入”这一系列操作不是原子操作(不可分割的整体)。两个线程的执行顺序交织在了一起,导致了错误的结果。这个“竞争”的就是谁先读取和谁先写入。


竞态条件产生的必要条件

  1. 存在共享资源(临界资源):比如上面的银行账户余额。
  2. 多个线程同时对该资源进行读写操作:如果都是只读操作,不会产生问题。
  3. 缺少同步机制:没有对共享资源的访问进行保护,使得操作不是原子的。

在编程中的实际例子

import threading# 共享资源
counter = 0def increment():global counterfor _ in range(100000):# 1. 读取counter的值到寄存器# 2. 将寄存器中的值+1# 3. 将新值写回countercounter += 1# 创建两个线程
t1 = threading.Thread(target=increment)
t2 = threading.Thread(target=increment)# 启动线程
t1.start()
t2.start()# 等待两个线程执行完毕
t1.join()
t2.join()# 预期结果:counter = 200000
print(f"Final counter value: {counter}")

运行这段代码,你很可能得不到预期的 200,000。因为 counter += 1 这个操作在底层并不是一步完成的,两个线程会互相覆盖对方的结果。


如何解决竞态条件?

解决竞态条件的核心思想是:将“读写共享资源”的关键代码段变成一个原子操作,即在同一时刻,只有一个线程可以执行这段代码。

常用的同步机制有:

  1. 互斥锁
    这是最常用的方法。线程在进入临界区(访问共享资源的代码)前先获取锁,如果锁已被其他线程占用,则等待;退出临界区时释放锁。
    import threadingcounter = 0
    lock = threading.Lock() # 创建一个锁def increment():global counterfor _ in range(100000):lock.acquire()   # 获取锁try:counter += 1 # 临界区finally:lock.release() # 释放锁# ... 其余代码相同
    
    现在,每次只有一个线程能执行 counter += 1,结果必然是 200,000。
  2. 信号量
  3. 监视器
  4. 使用线程安全的数据结构

总结

特性 描述
本质 结果依赖于不受控制的执行顺序。
发生场景 多线程/多进程并发读写共享资源时。
危害 导致数据不一致、程序行为不可预测、难以复现和调试的Bug。
解决方案 使用同步机制(如锁)来保证临界区的互斥访问。

简单来说,竞态条件就是一个因为“抢”资源而引发的混乱状态,而解决之道就是建立“排队”或“独占”的规则(锁)。

http://www.dtcms.com/a/429174.html

相关文章:

  • 邢台推广网站建设电话培训网站方案
  • 自媒体135网站学做网站可以赚钱吗
  • 邢台企业做网站价格网站建设有哪些规章制度
  • 新建网站seo优化怎么做网络营销方式及特点
  • WordPress状态栏替换英文外链seo兼职
  • 企业网站建立模板怎么做ui界面设计案例ppt
  • 南京电商网站建设公司湘潭网站建设开发
  • 怎样做自己的手机网站三九手机网手机响应式网站模版
  • 专业企业网站建设多少钱服务网站后台任务
  • 商务网站建设一万字wordpress添加关键词
  • 精通网站建设100全能建站密码北京网站建设龙鹏
  • DAY 35 模型可视化与推理-2025.9.30
  • 网站头部优化文字怎么做html怎么自己做网站
  • 2002年网站建设公司美词原创网站建设
  • 静安区网站建设工作作风
  • 网站开发公司的log开传奇怎么建设自己的网站
  • 做网站简单还是app简单响应式网站怎么样
  • 网站开发文件夹遂溪手机网站建设公司
  • 淘宝联盟怎么新建网站盐城优化办
  • 南阳网站建设域名公司大连网站建设策划
  • 扁平化资讯网站模板世界十大市场调研公司
  • 建设企业网站e路护航官网企业端外包一个项目多少钱
  • 黑龙江两学一做网站同城引流用什么软件
  • 网站制作哪些公司好外贸平台网站有哪些
  • vs网站制作如何让百度快速收录网站
  • 简单公司网站源码WordPress文章投票
  • 基于大数据的美食分析可视化平台: 美食大数据深度分析系统Python+Hadoop+Spark+LSTM预测(优秀项目)✅
  • 回龙观做网站怎么在网站后面制作官网俩个字
  • 上街免费网站建设建设视频网站费用吗
  • 网站 备案 异地steam账号注册网站