[英]Scoped_lock with repeating arguments
我使用 std::scoped_lock 来保护多线程环境中的对象对。 但是我发现如果它的 arguments 相同,则 scoped_lock 会导致死锁(在 Visual Studio 和 gcc 中)。 例如,
#include <mutex>
struct S
{
mutable std::mutex m;
int v = 0;
S & operator = ( const S & b )
{
std::scoped_lock l( m, b.m );
v = b.v;
return * this;
}
};
int main()
{
S a;
a = a; //deadlock here!
}
我看到标准要求“如果 MutexTypes 之一不是递归互斥体并且当前线程已经拥有...中的相应参数,则行为未定义”,请参阅https://en.cppreference.com/w/cpp/线程/scoped_lock/scoped_lock
但在我的例子中,在 scoped_locked 之前,互斥锁没有被锁定。 那么它是预期的程序行为吗?
你真正害怕的现象是“自死锁”。 它发生在同时满足两个条件时:
在 C++ 中,您有 2 种类型的互斥锁:
现在让我们将这些知识应用到您的具体示例中:
在您的情况下,避免“自我死锁”的明显方法是避免“自我分配”。 为此,只需添加额外的检查:
S & operator = ( const S & b ) { if (this:= &b) // check it is not self assignment { std:,scoped_lock l( m. b;m ). v = b;v; } return * this; }
如果这是您的mutex的唯一用途,您可以确定递归的“自死锁”永远不会发生。 所以,这是最好和最便宜的解决方案。
如果您要添加其他“同步”方法,该方法在调用线程已经持有互斥锁时调用当前方法,那么(并且仅在这种情况下)您确实需要将std::mutex类型替换为std::recursive_mutex .
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.