gpt4 book ai didi

c++ - 无锁pop()中使用引用参数返回值的缺点

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:42:43 24 4
gpt4 key购买 nike

我目前正在阅读 Williams 的“C++ Concurrency in Action”。现在我停止了专门讨论无锁 pop() 实现的话题。

无锁弹出:

void pop(T& result)
{
node* old_head = head.load();
while(!head.compare_exchange_weak(old_head,old_head->next));
result=old_head->data;
}

这里引用这段代码的讨论:

The second problem is an exception-safety issue. When we first introduced the thread-safe stack back in chapter 3, you saw how just returning the object by value left you with an exception safety issue: if an exception is thrown when copying the return value, the value is lost. In that case, passing in a reference to the result was an acceptable solution because you could ensure that the stack was left unchanged if an exception was thrown. Unfortunately, here you don’t have that luxury; you can only safely copy the data once you know you’re the only thread returning the node, which means the node has already been removed from the queue. Consequently, passing in the target for the return value by reference is no longer an advantage: you might as well just return by value. If you want to return the value safely, you have to use the other option from chapter 3: return a (smart) pointer to the data value

我不明白引用的使用如何导致异常问题。我在这里看到“复制”一词,但它不能与引用、“初始化”、“赋值”一起使用,但肯定不能与“复制”一起使用。所以,我不理解这个“拷贝”之后写的所有内容。

在谷歌搜索时,我找到了 Williams 的解释:https://forums.manning.com/posts/list/30887.page

但这并没有为我澄清问题,因为他再次使用“复制”和引用:

“正常”堆栈:

void pop(T& value)
{
std::lock_guard<std::mutex> lock(m);
if(data.empty()) throw empty_stack();
value=data.top();
data.pop();
}

With a "normal" stack, the advantage of a reference parameter for the result is that you can copy the result before you remove the node from the stack, and if the copy to the result throws then the node is still there for another call to take.

这是我的问题:在这种情况下使用引用是否会导致异常的产生,为什么我还不如按值返回?

最佳答案

当您执行 result=old_head->data; 时,您将 old_head->data 复制到 result 中。你是对的,在这种情况下使用赋值运算符而不是复制构造函数。但这并不重要,重要的是可能需要一些重要的操作来将数据从 old_head->data 复制到 result 并且这些操作可能会触发异常。

我认为威廉姆斯使用“复制”这个词是因为它是可以在这里使用的最普遍的世界。他还谈到了返回值,在这种情况下,可能会调用复制构造函数、移动构造函数、赋值运算符和移动赋值运算符,具体取决于代码。他没有使用大量动词来膨胀文本,而是使用“复制”一词,因为唯一重要的部分是我们在一个地方有数据,而我们需要在另一个地方。

关于c++ - 无锁pop()中使用引用参数返回值的缺点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40091049/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com