<五>基于CAS操作的atomic原子类型
2023-02-18 16:33:46 时间
C++11多线程类库中提供了
include
原子操作
若干汇编指令具有读-修改-写类型,也就是说它们访问存储器单元两次,第一次读原值,第二次写新值
假定运行在两个cpu上的两个内核控制路径试图通过执行非原子操作来同时读-修改-写同一个存储器。
首先两个cpu都试图读同一单元,然后使用不同的方式修改读取的内容之后将其写入该存储单元。
虽然最终两个写操作都会成功,但是全局结果是不对的,因为两个CPU写入同一内存单元,因此两个交错的读-修改-写操作成了一个单独的操作
避免由于"读-修改-写"指令引起的竞争条件的最容易的办法就是确保这样的操作在芯片级是原子的,任何一个这样的操作度必须以单个指令执行,中间不能中断,且避免其他的CPU访问同一存储器单元,这样很小的原子操作可以建立在其它更灵活机制的基础上以创建临界区。
窗口卖票案例中的 ticketCount++ ;ticketCount--不是线程安全的
我们原来是通过lock_guard(互斥锁) 来保证的
互斥锁是比较重的,对临界区代码做得事情稍微复杂,多的情况下 OK的.
但是对一些简单的情况,我们可以使用CAS来保证上面的 ++ --操作的原子特性就足够了,无需锁来操作.
C++11中的 automic头文件中包含了很多原子操作
volatile std::automic_bool isReadu=false;//volatile 不读缓冲中的值
volatile std::automic_int mycount=0;
void task(){
while(!isReady){
std::this_thread::yied();//线程出让当前的cpu时间片,等待下一次调度
}
for(int i=0;i<100;i++){
mycount++;
}
}
int main(){
list<std::thread> tlist;
for(int i=0;i<3;i++){
tlist.push_back(std::thread(task));
}
std::this_thread::sleep_for(std::chrono::sedonds(3));
isReady=true;
for(std::thread &t : tlist){
t.join();
}
}
相关文章
- 记一次 WinDbg 分析 .NET 某工厂MES系统 内存泄漏分析
- 记一次 .NET 某市附属医院 Web程序 偶发性CPU爆高分析
- 记一次 .NET 某妇产医院 WPF内存溢出分析
- 记一次 .NET 某化妆品 webapi 卡死分析
- 记一次 .NET 某智能服装智造系统 内存泄漏分析
- 记一次 .NET 某电商无货源后端服务 死锁分析
- 记一次 .NET 某公交卡扣费系统 程序卡死分析
- 记一次 .NET 某风控管理系统 内存泄漏分析
- 记一次 .NET 某资讯论坛 CPU爆高分析
- 记一次 .NET 某招聘网后端服务 内存暴涨分析
- 记一次 .NET 某电商定向爬虫 内存碎片化分析
- 记一次 .NET 某纺织工厂 MES系统 API 挂死分析
- 记一次 .NET 某上市工业智造 CPU+内存+挂死 三高分析
- 记一次 .NET 某新能源汽车锂电池检测程序 UI挂死分析
- ArrayPool 源码解读之 byte[] 也能池化?
- 记一次 .NET 某流媒体独角兽 API 句柄泄漏分析
- 记一次 .NET 某WMS仓储打单系统 内存暴涨分析
- 记一次 .NET 某智慧水厂API 非托管内存泄漏分析
- 记一次 .NET 某云采购平台API 挂死分析
- 记一次 .NET 某三甲医院HIS系统 内存暴涨分析