首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >GNU C++中的原子交换

GNU C++中的原子交换
EN

Stack Overflow用户
提问于 2010-03-19 23:15:53
回答 1查看 13.1K关注 0票数 19

我想确认我的理解是正确的。这类事情很棘手,所以我几乎可以肯定我遗漏了什么。我有一个由实时线程和非实时线程组成的程序。我希望非RT线程能够交换指向RT线程使用的内存的指针。

从文档中我的理解是,这可以在g++中通过以下方式完成:

代码语言:javascript
复制
// global
Data *rt_data;

Data *swap_data(Data *new_data)
{
#ifdef __GNUC__
    // Atomic pointer swap.
    Data *old_d = __sync_lock_test_and_set(&rt_data, new_data);
#else
    // Non-atomic, cross your fingers.                                          
    Data *old_d = rt_data;
    rt_data = new_data;
#endif
    return old_d;
}

这是程序中修改rt_data的唯一位置(初始设置除外)。当在实时上下文中使用rt_data时,它被复制到本地指针。对于old_d,稍后当确定旧内存未被使用时,它将在非RT线程中被释放。这是正确的吗?我需要volatile anywhere吗?还有没有我应该调用的其他同步原语?

顺便说一句,我是用C++来做这件事的,尽管我对C语言的答案是否不同很感兴趣。

提前谢谢你。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2010-03-20 00:03:06

在用C/C++编写并发代码时,通常不要使用volatile。volatile的语义与您想要的非常接近,以至于它很诱人,但最终volatilenot enough。不幸的是,Java/C# volatile != C/C++ volatile。Herb Sutter有一个很好的article来解释这个令人困惑的混乱。

你真正想要的是一个记忆栅栏。__sync_lock_test_and_set为您提供了隔离功能。

当您将rt_data指针复制(加载)到本地副本时,还需要一个内存栅栏。

无锁编程是很棘手的。如果你愿意使用Gcc的c++0x扩展,它会更简单一些:

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

std::atomic<Data*> rt_data;

Data* swap_data( Data* new_data )
{
   Data* old_data = rt_data.exchange(new_data);
   assert( old_data != new_data );
   return old_data;
}

void use_data( )
{
   Data* local = rt_data.load();
   /* ... */
}
票数 26
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2478397

复制
相关文章

相似问题

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