来自 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();
}
我的问题是,如果threadA处理#A2时threadB抛出异常怎么办?互斥锁已经锁定,但 lock_guard 可能还没有为互斥锁做好准备。