交换两个unique_ptr
s并不保证是线程安全的.
std::unique_ptr<T> a, b;
std::swap(a, b); // not threadsafe
Run Code Online (Sandbox Code Playgroud)
由于我需要原子指针交换,因为我喜欢所有权处理unique_ptr
,是否有一种简单的方法将它们组合起来?
编辑:如果这是不可能的,我愿意接受替代方案.我至少想做这样的事情:
threadshared_unique_ptr<T> global;
void f() {
threadlocal_unique_ptr<T> local(new T(...));
local.swap_content(global); // atomically for global
}
Run Code Online (Sandbox Code Playgroud)
在C++ 11中这样做的惯用方法是什么?
我想验证我的理解是否正确.这种事情很棘手,所以我几乎可以肯定我错过了什么.我有一个由实时线程和非实时线程组成的程序.我希望非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的答案是否不同感兴趣
提前谢谢.
在新标准 C++ 原子递增操作中,在递增值之前检查先决条件是否表明原子值小于指定值?
我可以比下面的代码更容易、更快吗?
int atomic_inc(std::atomic_int& val, int less_than) {
int new_val;
int old_val = val.load();
do
{
if (old_val > less_than) return old_val;
new_val = old_val + 1;
} while (!val.compare_exchange_weak(old_val, new_val));
return new_val;
}
Run Code Online (Sandbox Code Playgroud)
如果有人不知道compare_exchange_weak是如何工作的:compare_exchange_weak读取val,与old_val进行比较,如果不相等则将val保存到old_val。如果相等则将new_val保存到val。
有没有办法实现一种类型的引用,其值可以与另一个原子交换?
在Java中,我们AtomicReference
可以使用本地变量而不是其他变量进行交换AtomicReference
.
你可以做:
AtomicReference r1 = new AtomicReference("hello");
AtomicReference r2 = new AtomicReference("world");
Run Code Online (Sandbox Code Playgroud)
并将它们与两个操作组合交换:
r1.set(r2.getAndSet(r1.get()));
Run Code Online (Sandbox Code Playgroud)
但是这使得它们之间处于不一致状态,两者都包含在内"hello"
.即使你可以原子地交换它们,你仍然无法原子地读取它们(作为一对).
我希望能做的是:
PairableAtomicReference r1 = new PairableAtomicReference("hello");
PairableAtomicReference r2 = new PairableAtomicReference("world");
AtomicRefPair rp = new AtomicRefPair(r1, r2);
Run Code Online (Sandbox Code Playgroud)
然后
Object[] oldVal, newVal;
do {
oldVal = rp.get();
newVal = new Object[] {oldVal[1], oldVal[0]};
} while (! rp.compareAndSet(oldVal, newVal));
Run Code Online (Sandbox Code Playgroud)
交换值,并在另一个线程中:
AtomicRefPair otherRP = new AtomicRefPair(r1, r2);
System.out.println(Arrays.toString(otherRP.get()));
Run Code Online (Sandbox Code Playgroud)
并确保输出将是[hello, world]
或[world, hello]
.
笔记:
r1
并且r2
为此操作配对,但是另一个线程可能会独立配对,说r1 …
MSDN 说,互锁函数提供了一种简单的机制来同步访问由多个线程共享的变量。
如果变量位于进程的共享内存中,我不确定它们是否可以跨多个进程的线程工作。
同样,GNU GCC 编译器的内在函数:__sync_add_and_fetch 和 __sync_lock_test_and_set 怎么样?
atomic-swap ×5
atomic ×3
c++ ×3
c++11 ×2
g++ ×1
gcc ×1
interlocked ×1
java ×1
linux ×1
lock-free ×1
stdatomic ×1
unique-ptr ×1
windows ×1