标签: atomic-swap

两个unique_ptr <T>的无锁交换

交换两个unique_ptrs并不保证是线程安全的.

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中这样做的惯用方法是什么?

c++ lock-free unique-ptr atomic-swap c++11

38
推荐指数
2
解决办法
9808
查看次数

GNU C++中的原子交换

我想验证我的理解是否正确.这种事情很棘手,所以我几乎可以肯定我错过了什么.我有一个由实时线程和非实时线程组成的程序.我希望非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++ g++ atomic atomic-swap

18
推荐指数
1
解决办法
1万
查看次数

检查前提条件是否存在原子增量,即原子值小于指定值?

在新标准 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。

c++ atomic atomic-swap c++11 stdatomic

7
推荐指数
1
解决办法
3698
查看次数

可以创建可以原子交换的AtomicReference吗?

有没有办法实现一种类型的引用,其值可以与另一个原子交换?


在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 …

java interlocked atomicreference atomic-swap

6
推荐指数
1
解决办法
1640
查看次数

Win32 InterlockedIncrement 和 InterlockedExchange 跨进程是原子的吗?

MSDN 说,互锁函数提供了一种简单的机制来同步访问由多个线程共享的变量。

如果变量位于进程的共享内存中,我不确定它们是否可以跨多个进程的线程工作。

同样,GNU GCC 编译器的内在函数:__sync_add_and_fetch 和 __sync_lock_test_and_set 怎么样?

linux windows gcc atomic atomic-swap

2
推荐指数
1
解决办法
883
查看次数