gpt4 book ai didi

c++ - 这是交换(多线程)的异常安全实现吗?

转载 作者:行者123 更新时间:2023-11-30 02:53:22 25 4
gpt4 key购买 nike

摘自《C++ Concurrency in Action》一书的例子

例子(3.2.4)

friend void swap(X& lhs, X& rhs)
{
if (&lhs == &rhs)
return;
std::lock(lhs.m, rhs.m); #1
std::lock_guard<std::mutex> lock_a(lhs.m, std::adopt_lock); #2
std::lock_guard<std::mutex> lock_b(rhs.m, std::adopt_lock); #3
swap(lhs.some_detail, rhs.some_detail); 
}

如果我们在 #2 和 #3 时在另一个线程上抛出异常怎么办?

另一个示例 (3.2.6) 看起来更好(尽管由于 unique_guard 更昂贵而更慢且更大)

friend void swap(X& lhs, X& rhs)
{
if (&lhs == &rhs)
return;
std::unique_guard<std::mutex> lock_a(lhs.m, std::defer_lock); #1
std::unique_guard<std::mutex> lock_b(rhs.m, std::defer_lock); #2
std::lock(lhs.m, rhs.m); #3
swap(lhs.some_detail, rhs.some_detail); 
}

3.2.4的例子不是异常安全的吗?或者我想念什么?谢谢。

简单的例子

class some_big_object;
void swap(some_big_object& lhs,some_big_object& rhs);
class X
{
private:
some_big_object some_detail;
std::mutex m;
public:
X(some_big_object const& sd):some_detail(sd){}
friend void swap(X& lhs, X& rhs)
{
if(&lhs==&rhs)
return;
std::lock(lhs.m,rhs.m); #A1
std::lock_guard<std::mutex> lock_a(lhs.m,std::adopt_lock); #A2
std::lock_guard<std::mutex> lock_b(rhs.m,std::adopt_lock); #A3
swap(lhs.some_detail,rhs.some_detail);

}
};

void threadA()
{
X A, B;
//do something
swap(A, B);
}

void threadB()
{
//do something
throw std::runtime_error("error");
}

void testSwap()
{
std::thread tA(threadA);
std::thread tB(threadB);

tA.join();
tB.join();
}

我的问题是,如果threadB 在threadA 处理#A2 时抛出异常怎么办?互斥体已经锁定,但 lock_guard 可能还没有为互斥体准备好。

最佳答案

它们对我来说看起来异常安全。

在第一个示例中,相等比较可能会抛出异常,或者在#1 处对 std::lock 的调用可能会抛出异常,但如果抛出,函数将退出而不更改任何内容。 #2 和#3 处的对象初始化不能抛出,标准是这么说的。对 swap 的调用可能会抛出异常,但如果确实如此,互斥量将由 unique_lock 析构函数解锁。

在第二个例子中,相等比较可以抛出,#1 和#2 处的初始化是 noexceptstd::lock 调用可以抛出,但是如果它执行函数退出而没有任何影响。对 swap 的调用可能会抛出异常,但如果确实如此,互斥量将由 unique_lock 析构函数解锁。

您似乎在暗示单独线程中的异常与执行交换的线程交互,但事实并非如此。一个线程中的异常不会影响其他线程的执行。

关于c++ - 这是交换(多线程)的异常安全实现吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18047413/

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