在http://en.cppreference.com/w/cpp/atomic/atomic_compare_exchange上,以下示例代码作为示例使用std::atomic_compare_exchange_weak
:
void append(list* s, node* n)
{
node* head;
do {
head = s->head;
n->next = head;
} while(! std::atomic_compare_exchange_weak(s->head, head, n));
}
Run Code Online (Sandbox Code Playgroud)
我的理解是,这已经比较的效果*(s->head)
有head
,当我所相信的希望是比较s->head
用head
.std::atomic_compare_exchange_weak
在这个例子中&(s->head)
,第一个参数应该是,还是我错过了什么?
更新:规格std::atomic_compare_exchange_weak
说:
bool atomic_compare_exchange_weak(volatile A* object, C * expected, C desired) noexcept;
bool atomic_compare_exchange_weak(A* object, C * expected, C desired) noexcept;
Run Code Online (Sandbox Code Playgroud)
效果:原子地,比较对象指向的内存的内容...与预期中的内容相等...
我认为这意味着*object
与之相比较expected
,但进一步的研究表明,实际意义是*object
与之比较*expected
(即,"在expected
"中的意思是"指向expected
").这意味着我原来问题的答案是"不,没有必要s->head
在cppreference中获取示例代码中的地址".但object
必须指向a std::atomic<T>
和预期必须指向a 的事实T
使我很难弄清楚如何在cppreference处更正代码以便编译.我们想要将列表的头部与列表头部的副本进行比较,但如果列表的头部是类型std::atomic<T>*
,则T*
如果调用的话,副本必须是类型的std::atomic_compare_exchange_weak
是编译,我找不到一种方法来指定std::atomic<T>*
一个T*
没有a reinterpret_cast
.即使这样,第三个参数std::atomic_compare_exchange_weak
也需要是类型T
,但cppreference中的示例显示第二个和第三个参数属于同一类型.这告诉我,cppreference的例子被打破了.我试图修复它,但是我被使用了一个reinterpret_cast
只是感觉不对的需要而感到困扰.
有趣的是,在我试图弄清楚这些东西时,我检查了msdn页面std::atomic_compare_exchange_weak
,我很惊讶地看到该页面显示了原型std::atomic_compare_exchange_*strong*
!
有人可以发布用于std::atomic_compare_exchange_weak
在单链表的前面插入节点的合理代码吗?没有必要担心ABA问题或做任何花哨的事情.我只想看到编译的骨架代码.
小智 2
一个正确的例子是:
struct list {
std::atomic<node*> head;
};
...
void append(list* s, node* n)
{
node* head;
do {
head = s->head;
n->next = head;
} while (!std::atomic_compare_exchange_weak(&(s->head), &head, n));
// or while (!s->head.compare_exchange_weak(head, n));
}
Run Code Online (Sandbox Code Playgroud)
除非您想处理未定义的行为,否则需要list::head
是一个对象。std::atomic
相关平台可能需要std::atomic
使用锁来实现部分或全部功能。因此,std::atomic<T*>
可能会包含其他成员,并且reinterpret_cast<std::atomic<T*>*>
UB 意味着您的程序崩溃。
归档时间: |
|
查看次数: |
2013 次 |
最近记录: |