8

不断地阅读文档让我对boost::atomic接口是否应该支持非平凡类型感到困惑?std::atomicatomic

也就是说,给定一个(值)类型,只能通过将读/写封闭在一个完整的互斥锁中来进行写/读,因为它有一个非平凡的复制-ctor/赋值运算符,这应该由std::atomic(正如 boost 明确指出它是 UB)。

我是否应该为非平凡的类型提供文档谈论自己的专业化?


boost::function<bool (void)> simpleFn;注意:我之所以这样做,是因为我有一个需要自动设置/重置的跨线程回调对象。拥有一个单独的互斥体/临界区,甚至用简单的 set 将两者都包装在类似原子的辅助类型中,看起来很容易,但是有什么开箱即用的吗?

4

2 回答 2

6

Arne 的回答已经指出,标准要求std::atomic.

以下是为什么原子学首先可能不是解决您的问题的正确工具的一些理由:原子学是在 C++ 中构建线程安全数据结构的基本构建原语。它们应该是构建更强大的数据结构(如线程安全容器)的最低级构建块。

特别是,原子通常用于构建无锁数据结构。对于锁定数据结构原语std::mutexstd::condition_variable是一种更好的匹配方式,如果只是因为很难用原子编写阻塞代码而不引入大量的忙等待。

所以当你想到std::atomic第一个关联应该是无锁的(尽管大多数原子类型在技术上都允许有阻塞实现)。你描述的是一个简单的基于锁的并发数据结构,所以从概念的角度来看,将它包装在一个原子中应该已经感觉不对了。

不幸的是,目前尚不清楚如何用语言表达数据结构是线程安全的(我猜这是您首先使用原子的主要意图)。Herb Sutter 在这个问题上有一些有趣的想法,但我想现在我们只需要接受这样一个事实,即我们必须依靠文档来传达某些数据结构在线程安全方面的行为方式。

于 2013-05-03T10:30:44.440 回答
4

该标准规定(§29.5,1)

模板参数 T 的类型应该是可简单复制的

意思是不,您不能将类型与非平凡的 copy-ctor 或 assignment-op 一起使用。

但是,与命名空间 std 中的任何模板一样,您可以自由地将模板专门化为实现未专门化的任何类型。所以如果你真的想使用std::atomic<MyNonTriviallyCopyableType>,你必须自己提供专业化。该专业化的行为方式取决于您,这意味着您可以自由地吹掉您的腿或使用该专业化的任何人的腿,因为它超出了标准的范围。

于 2013-05-03T09:37:10.087 回答