是否可以使用 std::atomic 使类原子的复杂成员函数?
Posted
技术标签:
【中文标题】是否可以使用 std::atomic 使类原子的复杂成员函数?【英文标题】:Is it possible with std::atomic, make a complex member function of a class atomic? 【发布时间】:2013-06-10 11:40:59 【问题描述】:有可能做这样的事情吗?
...
class test
int i;
public:
test(int k):i(k);
void my()
cout<<i;
atomic<test> kk(0);
kk.test();
...
如果这是不可能的,那么如何调用函数以使其成为原子的?
【问题讨论】:
你为什么不试试呢? 谢谢,我试过了,它不知道t work that way. In kk there is no member function test. So i don
t 知道如何调用它。所以问。如何从kk调用测试???
如果你想要原子函数,你需要使用互斥体。 atomic<>
只给你a few operations on integers of various sizes。它不会神奇地使具有多个整数运算符的函数成为原子函数。
std::atomic<Ty>
对任意类型 Ty
进行了明确定义,前提是它们可以用 memcpy
复制并与 memcmp
比较相等性。
@WanderingLogic - 只要存储对象的大小足够小,std::atomic<Ty>
就可以无锁。我为 Dinkumware 编写的实现在所有情况下(包括数字类型)都使用 size 来确定是否使用锁。无论如何,我是在回应“atomic<>
只为您提供对各种大小的整数的一些操作”的断言。太窄了。
【参考方案1】:
std::atomic
的工作方式是使用处理器提供的某些指令。这些指令仅适用于特定大小的整数(不同的处理器对你能做什么和不能做什么有不同的限制和规则,在某些架构中,处理器架构甚至可能需要使用互斥锁或类似的功能来实现标准::原子)。
另请注意,std::atomic
的目的是确保值在多个处理器内核或多个处理器之间自动更新,这通常不是您想要/可以对更大的数据结构执行的操作。
要在其他数据结构上实现原子操作,您必须使用互斥锁或类似结构来确保以“线程原子”方式(不同于“处理器原子”)完成处理。
【讨论】:
C++ 规范的 31.8 [atomics.types.generic] 没有说明大小限制。只是它是简单的复制和移动构造和可分配的。另请注意static constexpr bool is_always_lock_free = implementation-defined;
成员。【参考方案2】:
您可以创建包含非数字对象的 std::atomic
对象。主要限制是包含的类型必须是可简单复制的;松散地说(因为它是这样实现的),这意味着用memcpy
复制是可以的,与memcmp
比较是有意义的。但是,它不允许您调用存储对象的成员函数。您必须复制存储的对象,进行更新,然后将结果复制回原子对象。
【讨论】:
在 OP 的示例中,失败的是调用kk.test()
。 atomic
与使 test()
函数正确执行而没有读取-修改-更新原子性问题完全无关。
@WanderingLogic - 我的最后两句话就是这么说的。以上是关于是否可以使用 std::atomic 使类原子的复杂成员函数?的主要内容,如果未能解决你的问题,请参考以下文章