atomic<shared_ptr<T>>在 GCC 和 Clang 的受支持程度真是一言难尽

18 小时 39 分钟前
 cnbatch

Clang 到现在都不支持atomic<shared_ptr<T>>,只能继续 atomic_load()atomic_store()。一旦要用 weak_ptr 则如同残废,不支持atomic_load()atomic_store()

GCC 12.2 及旧版本有“bug”( P0718R2 的疏忽),刚好 Debian 12 自带的 GCC 就是 12.2 ,直接完蛋。

这段代码在 Debian 12 (bookworm)无法编译,换成 Debian Testing (trixie)就可以成功编译:

#include <atomic>
#include <memory>

class A{ int a; };

int main()
{
    std::atomic<std::shared_ptr<A>> a_ptr = std::make_shared<A>();
    a_ptr = nullptr;

    return 0;
}

想要写跨编译器的代码很麻烦,只能加好几行#if #else #endif

Clang 原本已经有人在实现atomic<shared_ptr<T>>,准备到一半就放弃了:
[libc++] Implement P0718R2: atomic<shared_ptr<T>>
放弃的原因令人无语,因为 PR 内wait/notify_all的效率不太高,需要重写,作者直接不干了

927 次点击
所在节点    C++
11 条回复
Coelacanthus
16 小时 59 分钟前
GCC 12 分支最新的 fix 版本是 12.4 啊,Debian 他们居然没更新。你可以给他们提个 request 要求更新,理由就是有已知 bug 。
felixlong
16 小时 30 分钟前
把 shared_ptr 放到 atomic 里面的使用场景是什么?
cnbatch
13 小时 21 分钟前
@Coelacanthus 刚用 reportbug 命令向 Debian 提交了,暂时还没什么反应,就连编号都还没生成。
不太熟悉他们的流程,看来只能继续等待
cnbatch
13 小时 11 分钟前
@felixlong 多线程读写会用到,放进 atomic 就不需要再用 mutex 了。

举个例子,atomic<shared_ptr<Description>>,用来保存一段文字描述,修改时直接 make_shared<Description>,其他线程读取时调用 load() 成员函数或者用 std::atomic_load(),可以确保修改与读取互不干扰。对于时间敏感度不高的场景会很方便,起码不会死锁。
flax5a98aa2
12 小时 6 分钟前
https://en.cppreference.com/w/cpp/header/hazard_pointer 这个是不是更有盼头一点?
flax5a98aa2
12 小时 3 分钟前
[Lock-free Atomic Shared Pointers Without a Split Reference Count? It Can Be Done!]( <amp-youtube data-videoid="lNPZV9Iqo3U" layout="responsive" width="480" height="270"></amp-youtube>) 还有这个,我以前看没看懂,看到这个帖子想起来了,不知道是否对你有帮助
bruce0
11 小时 50 分钟前
同一个编译器, clang, 我记得 Mac 上的 clang 现在还不支持 std::jthread 呢(上半年还不支持,不知道现在支持了吗), linux 的 clang 是支持的
newma
1 小时 50 分钟前
@cnbatch 这个例子里面用不用 atomic 都没关系吧,make_shared 都另外 new 一个新对象了,返回一个全新的 shared_ptr 和全新的 Description 内存,这个过程和原来的那个 shared_ptr<Description>对象都没关系啊。
minami
1 小时 39 分钟前
msvc: 我看看现在还有没有黑子来黑我
changnet
1 小时 13 分钟前
首先 C++12 并不完全支持 C++20 ,要在 C++12 上使用 C++20 风险就比较大,因为用着用着就不知道哪个特性不支持,或者有 bug 。所以生产环境一般都不用这么新的标准

你这种情况,一般是自己用 SpinLock 之类的再实现一个类型来替代 std::atomic<std::shared_ptr<A>>

另外 std::atomic<std::shared_ptr<A>>只是对 std::shared_ptr 保证原子操作,对 A 里的数据操作并不是原子的。而 std::shared_ptr 本身的几个函数是线程安全的,你不修改 shared_ptr 本身的话 std::atomic 没啥意义。所以你这个需求还是比较小众的
changnet
1 小时 12 分钟前
@changnet GCC12 ,不是 C++12

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1081936

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX