c++ - 原子比较交换,但基于设置的标志,而不是平等?

标签 c++ multithreading concurrency atomic

std::atomic 提供 compare_exchange_strong(a,b) 测试基础值当前是否为“a”,如果是,则以原子/线程安全的方式将其替换为“b”。

是否有任何无锁、原子的方式来执行类似的操作,但不是测试与“b”是否相等,而是将“b”视为标志,如果基础值具有该标志则执行替换设置?

所以原则上,类似

bool compare_exchange_flags(std::atomic<int>& underlying, int& flag, int replacement)
{
  auto tmp = underlying.load();

  if((tmp & flag) == flag) // only perform replacement if flag is set
  {
    flag = tmp; // emulate compare_exchange_strong, where expected value is replaced with actual value
    underlying = replacement;
    return true;
  } else {
    flag = underlying.load();
    return false;
  }
}

只有在一个版本中……好吧,实际上可以工作;)(当然,以上操作根本不是原子的)

谢谢!


对于上下文:这是用于消息总线。该总线具有与某些状态(例如可读、可写)关联的内存区域。

每个状态都需要通过一些标志进行增强 - 例如,一个状态可以只是“WRITEABLE”,这意味着写入者可以自由地将数据写入片段(读者当前正在旋转/忙于轮询)。 或者它可以是“WRITEABLE | SIGNALED”,这意味着写入者可以获取此内存进行写入,但需要在写入数据后触发事件以通知读取者。

所以(从概念上讲,这不是实际的代码 - 只是粗略地演示)像

void send(...)
{
  auto expected = WRITEABLE;
  if(compare_exchange_flags(status, expected, WRITE_RESERVED))
  {
    // ... write data ...

    status = WRITTEN;

    if((expected & SIGNALED) = SIGNALED)
      wakeUpReaders();
  } else {
    tryAnotherRegion();
  }
}

最佳答案

没有这样的说明。但是这种操作通常是通过一个循环来执行的,该循环尝试在值具有标志时交换值:

bool replace_if_flag(std::atomic<int>& underlying, int flag, int replacement){

  auto tmp = underlying.load();

  if(!(tmp & flag)) return false;

  while (!underlying.compare_exchange_weak(tmp,replacement)){
    if(!(tmp & flag)) return false;
    }

  return true;
  }

关于c++ - 原子比较交换,但基于设置的标志,而不是平等?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54407134/

相关文章:

dictionary - 如何安全地允许当前访问go中的嵌套 map ?

c++ - C++ 是否提供了一种无需范围解析运算符即可访问类中类的方法?

c++ - 在 C++ 11 中使用来自 lambda 的值

c# - 异步 WCF REST 服务中跨线程的上下文

Kotlin 协程比线程花费更长的时间

使用 WSHttpBinding 时 WCF 并发请求堆积在服务器上

c++ - 编译器的健壮性……天真

c++ - 模数为哈希表中的地址创建错误的 int?

Java:循环等待直到ThreadPoolExecutor的任务完成再继续

c++ - 在 C++ 中,如何重用已完成执行的标准线程?