首页 > 其他分享 >理解原子变量之四:可见性、memory_order_acquire与 memory_order_release

理解原子变量之四:可见性、memory_order_acquire与 memory_order_release

时间:2024-11-23 18:59:01浏览次数:9  
标签:std 变量 acquire 原子 线程 memory data order

理解原子变量之二:从volatile到内存序-进一步的认识-CSDN博客里的实例3里面,我们看到,如果在一个线程里修改原子变量done,另一个线程读取done时,就会看到这个变化。这就是原子变量的可见性。其实这个认识是不全面的。在std::memory_order - cppreference.com

里面这样描述 可见性:

 最重要的是红线标出的这句话。它的意思是,假如如下两个条件同时满足:

1 a线程对某原子变量进行了写入操作,且使用了内存序memory_order_release,

2 b线程对同一个原子变量进行读操作,且使用了内存序memory_order_acquire

则b线程读取该原子变量后,不仅可以看到该原子变量的更新值(也就是a线程写入的值),还能看到a线程对该原子变量进行写入之前的所有其他的写操作的效果,不论是针对该原子变量的,还是针对其他变量的,也不论这些变量是不是原子变量,也不论使用何种内存序。

看下面示例(来自std::memory_order - cppreference.com

#include <atomic>
#include <cassert>
#include <string>
#include <thread>
 
std::atomic<std::string*> ptr;
int data;
 
void producer()
{
    std::string* p = new std::string("Hello");
    data = 42;//a线程写入原子变量前的写操作,data只是一个普通变量
    ptr.store(p, std::memory_order_release);//线程写入原子变量
}
 
void consumer()
{
    std::string* p2;
    while (!(p2 = ptr.load(std::memory_order_acquire)))//b线程读取原子变量
        ;
    assert(*p2 == "Hello"); // 绝无问题
    assert(data == 42); // 绝无问题,
//因为data=42这句话,发生在a线程写入原子变量之前,
//所以在b线程读取原子变量后,data的更新值对b线程是可见的
}
 
int main()
{
    std::thread t1(producer);//这就是线程a
    std::thread t2(consumer);//这就是线程b
    t1.join(); 
    t2.join();
}

尽管data是一个普通变量,但是data=42这个操作发生在ptr.store之前(且采用内存序release),所以consumer函数读取ptr.load之后(且采用内存序acquire),也可以看到data的最新值42

但是注意,假如还有第三个线程,且第三个线程不操作原子变量ptr,或者虽然操作ptr,但是使用比较弱的内存序,如前一篇所说的relaxed,则release之前发生的写入操作的效果,不一定能像使用acquire那样被第三个线程观察到。

标签:std,变量,acquire,原子,线程,memory,data,order
From: https://blog.csdn.net/liji_digital/article/details/143996082

相关文章

  • flume传输数据报错“Space for commit to queue couldn‘t be acquired. Sinks are li
        最近在写一个数据量比较大的项目时候,需要使用flume将kafka中的数据传输到HDFS上进行存储,方便后续的数仓搭建,但是flume在传输数据中却报错如下日志org.apache.flume.ChannelFullException:Spaceforcommittoqueuecouldn'tbeacquired.Sinksarelikelynot......
  • Java OOM (OutOfMemoryError) 的产生原因及解决方案(内存泄漏、内存溢出、对象生命周期
    在Java开发中,OutOfMemoryError(简称OOM)是常见的内存溢出错误,通常发生在Java虚拟机(JVM)无法分配所需内存时。OOM不仅仅意味着系统内存不足,它还可能由程序中的内存管理问题导致,如内存泄漏或资源未正确释放。本篇博客将全面、深入地分析OOM的产生原因,并给出有效的解决方案。1.O......
  • 停止训练后报错torch.cuda.OutOfMemoryError: CUDA out of memory. 及查看进程和停止
    停止训练后遇到 torch.cuda.OutOfMemoryError 错误,意味着你的GPU内存不足,无法分配更多内存给当前的PyTorch操作。查看进程并关闭相关进程就可恢复。在不同的操作系统中,查看进程的方法有所不同。以下是常见操作系统的命令:在Linux和macOS系统中,你可以使用以下几种方法来......
  • 收藏等于吃灰?SuperMemory:让信息不再迷失
    网上冲浪,永远在收藏,但是书到用时方恨少?你是否希望拥有一款工具,可以帮助你轻松管理、整理和检索所有重要信息?SuperMemory就是你需要的答案!它是一款强大的第二大脑工具,可以帮助你构建个人知识库,并轻松访问所有重要信息。 【使用场景】学习研究:保存有价值的文章、论文,构......
  • CITS2002 simulation of virtual memory
    CITS2002-SecondProjectAsimplesimulationofvirtualmemoryThisprojectisworth10%ofthemarksintheunit.Theprojectcanbedoneingroupsoftwo.TheduedateoftheprojectisOctober17,11:59pm.Theprojectdescriptionislong,butthe......
  • 论文分享-《GPU Memory Exploitation for Fun and Profit》
    1.研究问题该论文对NVIDIAGPU上不同内存空间(globalmemory,localmemory,sharedmemory)中存在的bufferoverflow问题进行了深入的研究,并成功对在GPU上运行的DNN应用实现了ROP攻击。以往的研究局限于单一内存空间中bufferoverflow的影响,没有对不同内存空间的跨......
  • 织梦错误Please set ‘request_order’
    当你在使用DedeCMS并遇到错误提示“DedeCMSError:(PHP5.3andabove)Pleaseset‘request_order’inivaluetoincludeC,GandP(recommended:‘CGP’)inphp.ini,more…”时,可以通过以下两种方法来解决这个问题:方法1:修改 php.ini 文件找到 php.ini 文件:......
  • 《 C++ 修炼全景指南:十三 》为什么你的代码不够快?全面掌控 unordered_set 和 unordere
    摘要本文深入探讨了C++标准库中的两大无序容器——unordered_set和unordered_map,从底层实现、核心操作、性能优化、实际应用等多个方面进行了全面分析。首先,文章介绍了这两种容器的基本概念,说明了它们基于哈希表实现的特点,尤其是在查找、插入和删除操作上具备常数时间......
  • 易优CMS出现:Allowed memory size of 134217728 bytes exhausted (tried to allocate 2
    当你遇到“Allowedmemorysizeof134217728bytesexhausted(triedtoallocate20480bytes)”的错误时,这意味着PHP的内存限制已经耗尽。这种错误通常发生在处理大量数据或执行复杂计算时。为了解决这个问题,可以采取以下几种方法:方法1:修改 php.ini 文件(推荐)找到 php......
  • 易优CMS登录后台报Allowed memory size of 134217728 bytes ex hausted (tried to alo
    当你在登录后台时遇到“Allowedmemorysizeof134217728bytesexhausted(triedtoallocate20480bytes)”的错误提示时,通常是由于PHP的内存限制不足导致的。以下是一些具体的解决步骤:步骤1:检查PHP配置登录宝塔面板登录宝塔面板。在左侧菜单栏选择“软件商店”。......