单写单读线程场景下Sensor类是否需要std::mutex?
单写单读场景下Sensor类是否需要使用std::mutex?
先看你的代码实现:
class Sensor { private: double data; // std::mutex mtx; public: Sensor() : data(0) {} void update(double value) { // std::lock_guard<std::mutex> lock(mtx); data = value; } double get_data() const { // std::lock_guard<std::mutex> lock(mtx); return data; } };
结论是:必须加同步机制(比如std::mutex),或者改用std::atomic
内存可见性无法保证
写线程修改data后,由于CPU缓存的存在,这个修改可能只停留在写线程的本地缓存,不会立刻同步到主存。读线程可能一直读取自己缓存里的旧值,永远看不到最新的传感器读数。而mutex的加解锁动作会触发内存屏障,强制缓存同步,确保读写线程看到的是一致的内存状态。32位系统下存在数据撕裂风险
double是64位类型,在32位系统中,写入操作需要拆成两次32位的内存操作来完成。如果读线程刚好在这两次操作之间读取data,就会拿到一个半旧半新的"撕裂值",完全不符合预期。就算是64位系统,C++标准也没有强制保证double的读写是原子操作,依赖平台特性会让代码失去可移植性。为未来扩展留余地
现在是单写单读,但需求随时可能变化——比如后续新增写线程。如果现在没加mutex,到时候代码会直接出现多写竞争问题,需要大面积重构。而且单线程场景下mutex的性能开销微乎其微,完全可以忽略。
如果觉得mutex有点重,也可以把data改成std::atomic<double>,它同样能保证内存可见性和原子性,代码更简洁,性能表现也不差。
内容的提问来源于stack exchange,提问作者BhanuKiran
相关产品推荐
相关产品推荐

