相关疑难解决方法(0)

用于线程控制的volatile bool被认为是错误的吗?

由于我对这个问题的回答,我开始阅读关键字volatile以及关于它的共识.我看到有很多关于它的信息,一些旧的现在看起来是错的,而且很多新的说它在多线程编程中几乎没有位置.因此,我想澄清具体的用法(在SO上找不到确切的答案).

我还想指出我一般都理解编写多线程代码的要求,以及为什么volatile不解决问题.不过,我看到代码volatile用于我工作的代码库中的代码.此外,这是我使用volatile关键字的唯一情况,因为所有其他共享资源都已正确同步.

假设我们有一个类:

class SomeWorker
{
public:
    SomeWorker() : isRunning_(false) {}
    void start() { isRunning_ = true; /* spawns thread and calls run */ }
    void stop() { isRunning_ = false; }

private:
    void run()
    {
        while (isRunning_)
        {
            // do something
        }
    }
    volatile bool isRunning_;
};
Run Code Online (Sandbox Code Playgroud)

为简单起见,有些事情被遗漏了,但重要的是创建了一个对象,它在新生成的线程中执行某些操作,检查a(volatile)布尔值以了解它是否应该停止.只要希望工作者停止,就会从另一个线程设置此布尔值.

我的理解是,volatile在这种特定情况下使用的原因只是为了避免任何将其缓存在循环寄存器中的优化.因此,导致无限循环.没有必要正确地同步事物,因为工作线程最终将获得新值?

我想知道这是否被认为是完全错误的,如果正确的方法是使用同步变量?编译器/架构/核心之间有区别吗?也许这只是一个值得避免的草率方法?

如果有人澄清这一点,我会很高兴.谢谢!

编辑

我有兴趣看到(在代码中)你如何选择解决这个问题.

c++ multithreading multicore volatile

27
推荐指数
4
解决办法
2万
查看次数

是否会在其他线程中始终以相同顺序看到对不同线程中不同位置的两次原子写操作?

与我之前的问题类似,请考虑以下代码

-- Initially --
std::atomic<int> x{0};
std::atomic<int> y{0};

-- Thread 1 --
x.store(1, std::memory_order_release);

-- Thread 2 --
y.store(2, std::memory_order_release);

-- Thread 3 --
int r1 = x.load(std::memory_order_acquire);   // x first
int r2 = y.load(std::memory_order_acquire);

-- Thread 4 --
int r3 = y.load(std::memory_order_acquire);   // y first
int r4 = x.load(std::memory_order_acquire);
Run Code Online (Sandbox Code Playgroud)

怪异的结果 r1==1, r2==0,并r3==2, r4==0有可能在C ++ 11内存模型下,这种情况下?如果我要全部替换std::memory_order_acq_rel成该std::memory_order_relaxed怎么办?

在x86上,这样的结果似乎是被禁止的,请参见此SO问题,但我一般是在询问C ++ 11内存模型。

奖励问题:

我们都同意,与std::memory_order_seq_cst怪异的结果不会在C ++ 11被允许。现在,赫伯·萨特(Herb Sutter)在他著名的- …

c++ concurrency memory-model c++11 stdatomic

4
推荐指数
3
解决办法
540
查看次数