什么是Race Condition?

article/2025/8/18 23:05:18

简介

race condition是多线程的应用程序中经常遇到的问题,本文章接下来会解释什么是race condition,如何检测到它们以及如何解决这类问题。

Race condition

从定义来说,race condition是代码中一些执行结果取决于其执行的相对时间或者多线程交错执行的判断条件。它的结果是不可预测的。如何一个程序中不存在race condition,那么它就是线程安全的(thread-safe)。

例如有个转账程序,假设有两个账户,里面的余额都是500,现在要分两次从A账户转账300到B账户,如下图:
在这里插入图片描述

这两次转账操作分别有一个线程执行。如果第二次转账是在第一次转账后发生的,那么第二次转账就会判断发现A账户余额不足,从而转账失败。
在这里插入图片描述
但是,如果这两次转账在两个线程内同时执行,那么就可能出现不可预测的结果。如下图,两个线程检查A账户月都是500,都进行了转账操作,结果A账户最后余额是-100,这样的结果明显是不正确的。
在这里插入图片描述
如上转账过程,由于线程的执行时机是任意的,所以执行的结果也是不可预测的。造成这一情况的正是race condition(上面判断账户是否大于300的判断)。为了避免race condition,所以的共享资源(在例子中两个账户的余额可以被多个线程读取操作,所以余额就是共享资源)必须原子性地操作。打到这个目标有两个方法,第一种是将多个操作封装成一个线程排他性的代码段(例如加锁),第二是从硬件上保证是这些操作的原子性。

Race condition的两个模式

Check-Then-Act

Race condition有两个模式,第一个就是上面的转账的例子,属于Check-Then-Act模式,这类模式通常是一个流程中有一个检查环节,通过检查的结果再决定后续怎么走。

懒加载是Check-Then-Act的第二例子,例如在单例模式中,懒汉模式如下:

class Singleton {public static Object singleton;public static Object getSingleton(){if (singleton == null) {singleton = new Object();}return singleton;}
}

上面的singleton == null就是一个race condition,根据上面的解决办法,最简单是加上synchronized关键字,让判断和赋值两个操作具有线程排他性。

Read-Modify-Write

Read-Modify-Write是race condtion的第二个模式。在大多数编程语言中,对一个变量的修改通常分为读取,修改,写入三个步骤。问题通常是对变量的并发的读取修改(至少有一个修改,纯读取是没问题的)引起的。例如:
在这里插入图片描述
由于count++不是原子操作,所以可能发生以下情形:
在这里插入图片描述
两个线程同时对count进行++操作,结果并没有加2。

如何检测race condition

race condition通常很难重现,定位和排除,因为问题发生依赖于特定的场景。即使写一个多线程的单元也不可以保证程序的100%的正确定,但有一些方法可以排除race condition。

如何避免race condition

1.避免使用共享变量

在多线程环境中,race condtion的出现往往伴随着共享变量,如上面例子中的账户余额和count变量,都可以被多个线程读取操作,那么避免问题发生最简单直接的办法就是避免使用共享变量。可以使用不可变对象或者线程本地对象(例如java中的threadlocal)。

2.使用同步或者原子操作

使用同步可以避免race condition的问题,但是线程同步往往伴随很多同步的性能开销,还可能导致死锁。两个办法是使用原子操作,例如java中的提供的原子类。


http://chatgpt.dhexx.cn/article/1giuhiMK.shtml

相关文章

免费教程·开源 | 从零开始制作ROS无人竞速车RACECAR教程

一、课程前提 自动驾驶汽车即将成为交通出行的主流工具之一,它以计算机、现代汽车产业技术为基础,以数字化、智能化为依托实现自动化驾驶,学习自动驾驶需要了解架构、环境感知、行为决策、规划路径,多传感器融合等一系列技术&…

Racecar 基于ROS通信机制的多点导航实验

基于ROS通信机制的多点导航实验 一、实验目的二、实验环境三、实验原理四、实验内容五、实验步骤1.获取rviz发送目标点的topic;2.对已经建好的图获取相应目标点的坐标(多个,即小车要去的目标),还没建图先完成建图&…

C语言的整数除法

c语言的整数除法是向下取整的。

C语言 从5~100之间找出能被5或7整除的数

从5~100之间找出能被5或7整除的数 算法分析&#xff1a;注意“或”的理解&#xff1a;或此或彼或彼此 #include "stdio.h" main( ) { int i;for(i5;i<100;i)if(i%50||i%70)printf("%d\t",i); }有伙伴问倒序输出&#xff1a; 在线编译C语言&#xff1a;…

C语言实现计算数字能否被3个数整除

C语言实现计算数字能否被3个数整除 编程实现&#xff1a;输入一个整数&#xff0c;判断它能否被3&#xff0c;5&#xff0c;7整除&#xff0c;并输出以下信息之一&#xff1a; ①能同时被3&#xff0c;5&#xff0c;7整除&#xff1b; ②能被其中两数(要指出哪两个)整除&#x…

C语言-求能被7或11整除的整数

本关任务&#xff1a;编写程序求[1&#xff0c;1000]范围内能被7或11整除&#xff0c;但不能同时被7和11整除的整数。按每行8个数&#xff0c;每个数占5个字符且以左对齐的格式进行输出。 #include<stdio.h> int main() {int i1;int count0;for(i1;i<1000;i){if((i%7…

c语言学习-判断一个数是否能被3整除

判断一个数是否能被3整除 在主函数中输入整型数据n,判断该数是否能被3整除&#xff0c;如果能被3 整除&#xff0c;输出“yes”,否则输出“no” 程序流程图&#xff1a; void main() { int a; printf("please enteraguess number:\n"); scanf("%d",&…

C语言--编写程序,输入一个整数,判断它能否被3,5,7整除

编写程序&#xff0c;输入一个整数&#xff0c;判断它能否被3,5,7整除&#xff0c;并输出下列信息之一&#xff1a; 能同时被3,5,7整除&#xff1b;能被x和y两个数整除&#xff1b;能被x整除&#xff1b;不能被3,5,7任一个数整除。 #include <stdio.h> void main() { in…

【C语言】数据整除判断

题目&#xff1a;C语言编程实现——输入一个整数&#xff0c;判断它能否被 3&#xff0c;5&#xff0c;7 整除&#xff0c;并输出以下信息之一&#xff1a; ①能同时被 3&#xff0c;5&#xff0c;7 整除&#xff1b; ②能被其中两数&#xff08;要指出哪两个&#xff09;整除…

C语言—整除问题、求余、赋值、逻辑运算符易错点

前言 &#x1f428;这一篇主要是讲那些老师可能不会讲&#xff0c;但是很多初学者都容易踩坑的地方 &#x1f914; 根据自己踩过的的坑整理了一下&#x1f927; 文章目录 前言一、整除问题1️⃣第一种情况&#xff1a;整数相除&#xff0c;抹去小数位2️⃣第二种情况&#xff…

东南大学本 硕 博论文中期答辩 毕业答辩ppt模板2021版

东南大学本硕博开题、中期、毕业论文答辩ppt模板 ppt模板样式如下&#xff1a; 如果对您有用 &#xff0c;欢迎点赞&#xff0c;关注和收藏&#xff0c;谢谢各位路官。 下载地址 https://download.csdn.net/download/Vertira/19026191

计算机硕士系统毕业论文答辩ppt,计算机硕士论文答辩ppt

为毕业生写计算机硕士论文答辩ppt提供计算机硕士论文答辩ppt范文参考,涵盖硕士、大学本科毕业论文范文和职称论文范文,包括论文选题、开题报告、文献综述、任务书、参考文献等,是优秀免费计算机硕士论文答辩ppt网站。 费孝通的博士论文答辩“花天酒地” 费孝通的博士论文答辩…

毕业生必看:硕士答辩注意事项!

通过本次硕士答辩感触最深的就是能从中学习到很多东西&#xff0c;而最主要的就是专家在审查论文的时候会有哪些点&#xff1f;在提问的过程中会提到什么问题&#xff1f;还有就是各位师弟师妹们在陈述自己论文的时候要结合自己PPT重点的引导专家看论文等等&#xff0c;具体本次…

热搜!硕士答辩看到一篇非常惊喜的论文,网友直呼:求导师分享全文

点击上方“视学算法”&#xff0c;选择加"星标"或“置顶” 重磅干货&#xff0c;第一时间送达 本文整理自微博、中国青年报&#xff08;ID&#xff1a;zqbcyol &#xff09;、澎湃新闻、中国知网 近日&#xff0c;#硕士答辩看到一篇非常惊喜的论文#词条登上微博热搜&…

Git远程仓库—Github

一、创建远程仓库 以下操作为演示在Github网站上创建远程仓库 1.登陆注册Github2.创建仓库入口 3.编辑仓库信息 4.仓库创建完成 5.查看仓库地址 远程仓库地址 https://github.com/qruihua/info.git 二、配置SSH 选择SSH操作 如果某台电脑需要与Github上的仓库交互&#xff0c…

Git远程仓库与分支管理

文章目录 Git远程仓库什么是远程仓库什么是GitHub环境搭建添加远程库从远程库克隆 Git分支管理创建与合并分支解决冲突分支管理策略Bug分支Feature分支多人协作Rebase Git远程仓库 什么是远程仓库 远程仓库就是 在公网服务器上的仓库。 Git离线提交的原理就是&#xff1a;修改…

【Linux】使用git 连接到远程gitee仓库

一.创建gitee仓库 登陆到自己的gitee&#xff0c;点击新建仓库 输入仓库名称&#xff0c;注意gitee初次创建仓库时只能设置成私有的 创建后的页面是这样的&#xff0c;复制HTTPS 二.git三板斧 1.安装git 打开xshell&#xff0c;输入命令&#xff1a; yum install git 可以输入…

Git本地远程仓库的搭建(局域网内的提交和推送)

需要和同事一起开发一个Unity项目&#xff0c;所以要用到git&#xff0c;这东西以前都是公司的主程搭建好的&#xff0c;现在需要自己弄&#xff0c;虽然很简单的东西&#xff0c;但是也搞了好久。 之前就搭建过一次局域网git&#xff0c;当时就花了2天时间&#xff0c;现在要…

git远程仓库使用流程

git远程仓库使用流程 远程仓库使用流程远程仓库介绍远程仓库使用流程如何将本地文件夹关联远程仓库 多人开发配置流程远程仓库SSH配置远程仓库使用流程总结git分支使用流程分支介绍1.2-分支使用流程 远程仓库使用流程 Git命名作用详细描述git clone克隆远程仓库代码把服务器的…

Git远程仓库配置SSH(以github为例)

1. 设置本地git账户邮箱和用户名 输入命令git config --global user.name "Git账号"以及git config --global user.email "Git邮箱"。 输入命令git config --global --list&#xff0c;查看配置是否正确。 2. 生成新的SSH密钥 输入命令ssh-keygen -t…