gpt4 book ai didi

c++ - std::atomic bool 变量的访问顺序

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:26:56 25 4
gpt4 key购买 nike

我有一个函数可以访问(读取和写入)std::atomic<bool>多变的。我试图了解指令的执行顺序,以便决定原子是否足够或者我是否必须在这里使用互斥锁。功能如下-

// somewhere member var 'executing' is defined as std::atomic<bool>`

int A::something(){

int result = 0;
// my intention is only one thread should enter next block
// others should just return 0
if(!executing){
executing = true;

...
// do some really long processing
...

result = processed;
executing = false;
}

return result;
}

我读过这个page关于提到的 cppreference -

Each instantiation and full specialization of the std::atomic template defines an atomic type. If one thread writes to an atomic object while another thread reads from it, the behavior is well-defined (see memory model for details on data races)

和内存模型page提到了以下内容-

When an evaluation of an expression writes to a memory location and another evaluation reads or modifies the same memory location, the expressions are said to conflict. A program that has two conflicting evaluations has a data race unless either

  • both conflicting evaluations are atomic operations (see std::atomic)

  • one of the conflicting evaluations happens-before another (see std::memory_order)

If a data race occurs, the behavior of the program is undefined.

在它的下方略微写着 -

When a thread reads a value from a memory location, it may see the initial value, the value written in the same thread, or the value written in another thread. See std::memory_order for details on the order in which writes made from threads become visible to other threads.


这让我有点困惑,上面 3 个陈述中的哪一个实际上发生在这里?

当我执行 if(!executing){ 时这条指令在这里是原子指令吗?更重要的是-是否保证没有其他线程会进入 if 循环,如果有两个线程会进入 if body,因为第一个线程会设置 executingtrue

如果提到的代码有问题,我应该如何重写它以反射(reflect)初衷..

最佳答案

如果我没理解错的话,您是在尝试确保只有一个线程会同时执行一段代码。这正是互斥锁的作用。由于您提到如果互斥量不可用,您不希望线程阻塞,您可能想看看 std::mutextry_lock() 方法>。查看documentation of std::mutex .

现在说明为什么您的代码无法按预期工作:稍微简化一下,std::atomic 保证在并发访问变量时不会出现数据竞争。 IE。有一个明确定义的读写顺序。这不足以满足您要执行的操作。想象一下 if 分支:

if(!executing) {
executing = true;

请记住,只有executing 上的读写操作是原子的。这至少使否定 !if 本身不同步。对于两个线程,执行顺序可能是这样的:

  1. 线程 1 读取正在执行(原子地),值为 false
  2. 线程 1 否定从执行读取的值,value = true
  3. 线程1评估条件并进入分支
  4. 线程 2 读取 executing(原子地),值为 false
  5. 线程 1 将 executing 设置为 true
  6. 线程 2 否定值,该值被读取为 false,现在再次为 true
  7. 线程2进入分支...

现在两个线程都进入了分支。

我会按照以下思路提出一些建议:

std::mutex myMutex;

int A::something(){

int result = 0;
// my intention is only one thread should enter next block
// others should just return 0
if(myMutex.try_lock()){

...
// do some really long processing
...

result = processed;
myMutex.unlock();
}

return result;
}

关于c++ - std::atomic bool 变量的访问顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39870194/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com