You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用std::atomic_flag作为同步机制删除共享状态是否安全合规?

用std::atomic_flag同步双线程共享状态的删除是否安全合规?

问题背景

我有一个被两个线程并发使用的共享状态,当两个线程均不再使用该状态时,它已无存在价值,必须被删除。想确认是否可以安全、合规地使用std::atomic_flag作为同步机制,来决定由哪个线程执行该共享状态的删除操作。

项目场景:存在一个由这类状态组成的自定义链表,目标是防止链表无限增长。若指定单个线程拥有状态的所有权,该线程需要定期执行清理操作,我希望避免这种机制,能在两个线程均使用完毕后立即删除链表节点。

代码示例

#include <atomic>
#include <thread>

struct State
{
    std::atomic_flag flag;

    auto eliminate() {
        // 设置flag表示线程已用完状态;第二个线程执行删除操作
        if (flag.test_and_set())
            delete this;
    }
};

int main()
{
    auto s = new State{};
    auto t1 = std::thread{[=] { s->eliminate(); }};
    auto t2 = std::thread{[=] { s->eliminate(); }};
    t1.join();
    t2.join();
}

分析与结论

核心逻辑的安全性

你的核心思路是可行的,但现有代码存在一个关键问题:std::atomic_flag未初始化。std::atomic_flag默认是未初始化状态,直接使用会导致未定义行为,必须用ATOMIC_FLAG_INIT完成初始化。

修正后的代码(初始化atomic_flag):

struct State
{
    std::atomic_flag flag = ATOMIC_FLAG_INIT; // 强制初始化flag为未设置状态

    auto eliminate() {
        if (flag.test_and_set())
            delete this;
    }
};

在修正初始化问题后,这个实现是安全且符合C++标准的:

  1. 原子操作的同步性:test_and_set()是原子操作,默认使用memory_order_seq_cst内存顺序,保证两个线程对flag的操作有全局一致的执行顺序。第一个调用eliminate()的线程会将flag设为true并返回false,不会执行delete this;第二个线程调用时,test_and_set()返回true,执行删除操作,不会出现重复删除或漏删的情况。
  2. delete this的合规性:C++标准允许delete this,只要满足两个条件:对象是通过new分配的,且delete之后不再访问该对象的任何成员。这里第一个线程在test_and_set()之后没有访问State的任何成员,第二个线程执行delete后也不会再访问,完全符合要求。

必须遵守的约束

  1. 严格控制调用次数:必须确保恰好只有两个线程调用eliminate()。如果超过两个线程调用,会导致多个线程执行delete this,触发多次释放同一内存的未定义行为;如果少于两个线程,对象永远不会被删除。
  2. 调用后的访问限制:任何线程在调用eliminate()之后,绝对不能再访问该State对象(包括调用成员函数、访问成员变量、通过指针/引用间接访问),否则会触发访问已释放内存的未定义行为。
  3. 链表场景的额外注意:在自定义链表中使用时,必须确保在调用eliminate()之前,该节点已经从链表中移除,或者其他线程不会再尝试访问该节点。否则可能出现其他线程访问已被删除的链表节点,导致程序崩溃或数据损坏。

总结

在正确初始化std::atomic_flag,且严格遵守调用次数、访问限制等约束的前提下,这个实现可以安全、合规地完成双线程共享状态的即时删除,避免单线程定期清理的开销。

内容的提问来源于stack exchange,提问作者Maarten Bamelis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 01:53:15