我想之间的差异std::lock(),并std::try_lock() 只在try_lock(),如果锁不可用,立即就会在的情况下返回false时std::lock(),它会阻塞状态去.
void lock( Lockable1& lock1, Lockable2& lock2, LockableN&... lockn );
Run Code Online (Sandbox Code Playgroud)
使用死锁避免算法锁定给定的Lockable对象lock1,lock2,...,lockn 以避免死锁.
int try_lock( Lockable1& lock1, Lockable2& lock2, LockableN&... lockn);
Run Code Online (Sandbox Code Playgroud)
尝试通过从第一个开始按顺序调用try_lock来锁定每个给定的Lockable对象lock1,lock2,...,lockn .
我有以下两个问题:
std::lock()提供死锁避免但std::try_lock不是?std::lock,锁的顺序无关紧要(它可能是lock2,锁3,lock1,...),同时按std::try_lock()顺序保持锁(lock1,lock2,lock3 ....)
- 为什么std :: lock()提供了死锁避免但是std :: try_lock没有?
它不需要.如果try_lock未能锁定所有成员,则会释放所有成员.try_lock如果另一个线程拥有部分或全部这些资源,您将无法获得死锁,因为您将立即返回.
来自try_lock:
如果对try_lock的调用失败,则不再执行try_lock调用,将为任何锁定的对象调用unlock,并返回无法锁定的对象的从0开始的索引.
- 为什么在std :: lock中,锁的顺序无关紧要(它可能是lock2,lock 3,lock1,...)而在std :: try_lock()中维护的顺序是保持的(lock1,lock2,lock3 .. ..)
我怀疑是因为轻松.不需要死锁避免算法,因为您要么锁定所有这些算法,要么无法锁定一个,在这种情况下您将释放所有这些算法.因此,最简单的锁定方法是try_lock从第一个开始并通过可变参数模板列表.此外,返回值表示它将返回第一个失败锁的索引.为了实现这一点,您必须从左到右进行迭代.
答案很简单.std::try_lock不需要死锁避免机制,因为如果没有特定的锁,它将立即返回并解锁所有获得的锁.另一方面,std::lock()只有在获得所有锁并且将它们锁定后才应该返回 - 这就是为什么它需要避免死锁的原因.
考虑2个锁A和B的情况.假设,线程2拥有锁B,并且希望锁定A.同时,线程1想要锁定A和B. std::try_lock在线程1处调用,将会发生什么发生的是A被成功锁定,失败的尝试锁定B,之后A被解锁(并且函数返回false) - 并且线程2成功锁定A.
另一方面,如果a std::lock不使用死锁避免,并且线程1要调用它,则事件序列将是:线程1锁定A,线程1尝试锁定B并在此处停止,线程2尝试锁定A并在这里停止.而这一点,两个线程都没有进展,我们有一个经典的死锁.