阅读boost::atomic
和std::atomic
上的文档,让我对atomic
接口是否支持非平凡类型感到困惑?
也就是说,给定一个(value-)类型只能通过将读/写封装在一个完整的互斥锁中来写入/读取,因为它有一个非平凡的copy-ctor /赋值运算符,这应该是由std::atomic
支持(因为提升明确指出它是UB)。
我是否应该提供专业化docs谈论我自己的非平凡类型?
注意:我正在尝试这个,因为我有一个需要以原子方式设置/重置的跨线程回调对象boost::function<bool (void)> simpleFn;
。有一个单独的互斥/临界区,或者甚至用简单的集合包装在类似原子的助手类型中,看起来很容易,但是有没有开箱即用的东西?
答案 0 :(得分:4)
Arne的回答已经指出,该标准要求std::atomic
的可复制类型。
这里有一些基本原理为什么原子可能不是最适合你的问题的工具:Atomics是用C ++构建线程安全数据结构的基本构建原语。它们应该是构建更强大的数据结构(如线程安全容器)的最低级构建块。
特别是,atomics通常用于构建无锁数据结构。对于锁定数据结构,像std::mutex
和std::condition_variable
这样的原语是一种更好的匹配,如果只是因为很难用原子编写阻塞代码而不引入大量繁忙的等待。
因此,当您想到std::atomic
时,第一个关联应该是无锁(尽管事实上大多数原子类型在技术上都允许具有阻塞实现)。您所描述的是一个简单的基于锁的并发数据结构,因此从概念的角度来看,将它包装在原子中应该已经感觉不对了。
不幸的是,目前尚不清楚如何用语言表达数据结构是线程安全的(我猜这是你首先使用原子的主要意图)。 Herb Sutter在这个问题上有some interesting ideas,但我想现在我们只需要接受这样一个事实,即我们必须依靠文档来传达某些数据结构在线程安全方面的行为。
答案 1 :(得分:3)
该标准规定了(§29.5,1)
模板参数T的类型应该是可以轻易复制的
意思是,你不能使用带有非平凡复制者或赋值操作的类型。
但是,与命名空间std中的任何模板一样,您可以自由地将模板专门用于实现尚未专门用于的任何类型的模板。所以如果你真的想使用std::atomic<MyNonTriviallyCopyableType>
,你必须自己提供专业化。这种专业化的行为取决于你,这意味着,你可以自由blow off your leg或使用该专业化的任何人,因为它超出了标准的范围。