首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >std::atomic_store和std::atomic_exchange不交换

std::atomic_store和std::atomic_exchange不交换
EN

Stack Overflow用户
提问于 2016-01-28 22:17:17
回答 4查看 2.8K关注 0票数 4

根据en.cppreference.com的说法,std::atomic_exchangestd::atomic_store相当于线程安全的std::swap.但这不是我在g++或clang++上得到的行为。

问题就在科鲁身上。 (见下文)

不过,它会打印这个:

代码语言:javascript
复制
std::atomic_store

a: 0x1ed2c30    0
b: 0x1ed2c50    1

a: 0x1ed2c50    1
b: 0x1ed2c50    1

std::atomic_exchange

a: 0x1ed2c50    0
b: 0x1ed2c30    1

a: 0x1ed2c30    1
b: 0x1ed2c30    1

为什么会这样呢?我做错了什么吗?我看错文件了吗?

代码列表

代码语言:javascript
复制
#include <iostream>
#include <memory>

int main()
{
    {
        std::cout << "std::atomic_store\n\n";
        auto a = std::make_shared<int>(0);
        auto b = std::make_shared<int>(1);

        std::cout
        << "a: " << a.get() << '\t' << *a << '\n'
        << "b: " << b.get() << '\t' << *b << '\n' << std::endl;

        std::atomic_store(&a, b);

        std::cout
        << "a: " << a.get() << '\t' << *a << '\n'
        << "b: " << b.get() << '\t' << *b << '\n' << std::endl;
    }
    {
        std::cout << "std::atomic_exchange\n\n";
        auto a = std::make_shared<int>(0);
        auto b = std::make_shared<int>(1);

        std::cout
        << "a: " << a.get() << '\t' << *a << '\n'
        << "b: " << b.get() << '\t' << *b << '\n' << std::endl;

        std::atomic_exchange(&a, b);

        std::cout
        << "a: " << a.get() << '\t' << *a << '\n'
        << "b: " << b.get() << '\t' << *b << '\n' << std::endl;
    }
}
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2016-01-28 22:25:43

这种描述有点误导人。

上面写着,例如,

代码语言:javascript
复制
template<class T>
void atomic_store( std::shared_ptr<T>* p,
                   std::shared_ptr<T> r );

“有效”做p->swap(r)。从它得到的角度来看,这是正确的(实际上,标准也是这么说的)。

但是,r是一个由值传递的函数参数,因此在函数返回之前被销毁。它不会影响来电者的任何事情。

票数 11
EN

Stack Overflow用户

发布于 2016-01-28 22:23:21

std::atomic_exchange不交换a和b,它将a设置为b并返回a的前一个值。

你可以这样做:

代码语言:javascript
复制
b = std::atomic_exchange(&a, b);

这将如您所期望的那样工作(交换a和b的指针),但这不是线程安全的:如果多个线程同时访问对象b,则这是未定义的行为。您不能做得更好,因为共享指针是一个复杂的结构,通常包含两个数据成员(两个指针)。由于原子无锁交换需要硬件支持,这只适用于基本类型(整数和指针)。

票数 2
EN

Stack Overflow用户

发布于 2016-01-28 22:20:31

很久以来,我一直很困惑为什么“比较和交换”中有swap。它不能交换任何东西。如果,它将设置值,如果检查失败,则返回当前值。因此,atomic_exchange绝不等同于std::swap。

相反,它是一种检查和设置模式,所以我总是更喜欢CAS,而不是表示比较集。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35073200

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档