Ste*_*eve 18 c++ g++ atomic atomic-swap
我想验证我的理解是否正确.这种事情很棘手,所以我几乎可以肯定我错过了什么.我有一个由实时线程和非实时线程组成的程序.我希望非RT线程能够将指针交换到RT线程使用的内存.
从文档中,我的理解是,这可以通过以下方式实现g++:
// 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;
}
Run Code Online (Sandbox Code Playgroud)
这是程序中唯一rt_data被修改的地方(初始设置除外).当rt_data在实时上下文中使用,它被复制到本地指针.对于old_d以后,当确定未使用旧内存时,它将在非RT线程中释放.它是否正确?我需要volatile在任何地方吗?我应该调用其他同步原语吗?
顺便说一下,我在C++中这样做,虽然我对C的答案是否不同感兴趣
提前谢谢.
def*_*ode 25
一般volatile在编写并发代码时不要使用C/C++.语义volatile是如此接近你想要的它是诱人的但最终挥发性是不够的.不幸的是Java/C# volatile != C/C++ volatile.Herb Sutter有一篇很棒的文章解释了令人困惑的混乱.
你真正想要的是记忆围栏. __sync_lock_test_and_set为您提供围栏.
将rt_data指针复制(加载)到本地副本时,还需要一个内存栏.
无锁编程很棘手.如果你愿意使用Gcc的c ++ 0x扩展,那就更简单了:
#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();
/* ... */
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
12468 次 |
| 最近记录: |