C++中std::atomic<A>访问内存池的线程并发访问问题咨询
多线程下原子对象的访问与行为问题
通过malloc()分配内存池,使用std::atomic<A>*指针对内存池进行读写,其中<A>可以是平凡可复制类或任意标准类型,且操作该内存池的对象可能被多线程调用。
现有场景疑问:某线程获取内存池特定地址的std::atomic<Record>对象引用并执行逻辑操作时,另一线程能否引用同一个原子对象?该线程会等待此对象被“释放”,还是会直接去获取其他未被引用的对象?
对应的实现代码:
std::atomic<Record> * it_record{&memory_address}; // memory_address由malloc()分配得到 for(size_t i{0U}; i < m_nbr_record; ++i) { Record tmp = *it_record; if (tmp == target_record) { *it_record = new_record; found = true; break; } ++it_record; }
核心结论
- 另一线程完全可以引用同一个原子对象:
std::atomic本身就是为多线程并发访问设计的,它的所有读写操作都是原子性的,不会触发数据竞争导致的未定义行为,但前提是Record类型满足std::atomic的要求(必须是平凡可复制类型,且大小适配硬件层面的原子操作支持)。 - 不会自动等待对象“释放”:
std::atomic没有内置锁或等待机制,除非你自行实现同步逻辑。另一个线程不会因为当前线程正在访问该原子对象就阻塞,它会直接执行自己的读写操作——这些操作通过硬件原子指令(如CAS、内存屏障)保证数据一致性。 - 当前代码的潜在问题:
- 代码中的查找+替换逻辑并非原子操作:如果两个线程同时查找同一个
target_record,可能出现竞态——线程A刚加载完tmp,线程B已将该位置替换为new_record,线程A随后执行替换操作会覆盖线程B的修改。 malloc()分配的内存可能存在对齐问题:直接将malloc()返回的内存当作std::atomic<Record>使用,需确保内存对齐符合std::atomic<Record>的要求,否则会触发未定义行为。建议使用std::allocator或new std::atomic<Record>[m_nbr_record]来分配内存,规避对齐风险。
- 代码中的查找+替换逻辑并非原子操作:如果两个线程同时查找同一个
内容的提问来源于stack exchange,提问作者Iván Sanz
相关产品推荐
相关产品推荐

