跨多个线程和 CPU 安全修改和读取布尔值的选项有哪些?

som*_*ous 0 c++ multithreading multiprocessing

我有一些 C++ 代码,大致包含以下逻辑:

class wrapper_info {
public:
        bool isConnected();
        void connectedHandler();
        void disconnectedHandler();
protected:
        bool _connected;
}

void wrapper_info::connectedHandler() {
        _connected = true;
}

void wrapper_info::disconnectedHandler() {
        _connected = false;
}

bool wrapper_info::isConnected() {
        return _connected;
}

extern "C"
bool is_connected(void *obj) {
        wrapper_info *wrapper_obj = reinterpret_cast<wrapper_info*>(obj);
        return wrapper_obj->isConnected();
}

Run Code Online (Sandbox Code Playgroud)

由于大多数我无法控制的原因,不同的线程(在不同的 CPU 内核上运行)按以下方式调用这些函数。

线程 1、2、3is_connected(obj)

线程2connectedHandler()连接发起时。

disconnectedHandler()当连接断开时线程3 。

我认为,如果重复调用 和connectedHandler(),可能会出现问题disconnectedHandler(),两个线程写入的问题_connected以及写入的顺序会出现问题,从而导致错误的最终值。民意调查也可能存在问题_connected

我的问题是:

  1. 单独的线程轮询和修改 的值实际上可能会引起哪些潜在问题_connected
  2. 有什么选择可以防止这些情况发生?也许做_connected一个volatile bool可能会解决轮询价值的问题。我还在考虑线程 2 和 3 修改其值的问题,也许将其设为原子 bool 并使用原子集操作将足以防止诸如乱序内存操作之类的问题。我还知道其他潜在的解决方案是锁或内存屏障,例如 smb_mb。但是,我不确定应该使用什么。

非常感谢。

Dre*_*ann 6

单独的线程轮询和修改 _connected 的值实际上可能会引起哪些潜在问题?

无论如何,这都是未定义的行为。

有什么选择可以防止这些情况发生?

一个常见的解决方案是使用std::atomic<bool>而不是bool.

有更奇特(并且更复杂)的方法来确保线程之间的同步,但这std::atomic是一个很好的首选,并且正确使用并不困难。

也许做_connected一个volatile bool可以解决问题

不会的。 volatile没有解决线程同步问题