【发布时间】:2021-11-10 19:57:24
【问题描述】:
我有一些 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();
}
由于我无法控制的原因,不同的线程(在不同的 CPU 内核上运行)以下列方式调用这些函数。
线程 1、2、3:is_connected(obj)
线程 2:连接启动时connectedHandler()。
线程 3 disconnectedHandler() 连接断开时。
我认为如果重复调用connectedHandler() 和disconnectedHandler() 可能会出现问题,两个线程写入_connected 时出现问题并且写入出现故障,从而导致最终值错误。轮询_connected 也可能存在问题。
我的问题是:
- 单独的线程轮询和修改
_connected的值实际上会产生哪些潜在问题? -
有哪些选项可以防止这些情况发生?也许将
_connected设置为volatile bool可能会解决轮询值的问题。我还在考虑线程 2 和 3 修改其值的问题,也许将其设为原子 bool 并使用原子集操作将足以防止诸如乱序内存操作之类的问题。我也知道其他潜在的解决方案是锁或内存屏障,如 smb_mb。但是,我不确定应该使用什么。
非常感谢。
【问题讨论】:
-
使其成为原子 bool 并使用原子集操作将足以防止诸如乱序内存操作之类的问题 是的,这样做。
volatile不是线程同步技术。 -
使用 std::atomic,或者如果您需要做的不仅仅是设置一个布尔值,请使用 std::unique_lock 和 std::mutex。但你是对的,你必须做点什么
-
仅供参考,没有 C/C++ 代码之类的东西。您的代码使用
class关键字,因此它是 C++ 而不是 C 语言。我强烈建议不要混合这两种语言,这会使您的程序更复杂,增加更多缺陷并且更难维护。
标签: c++ multithreading multiprocessing