为什么解锁已经被另一个线程锁定的互斥锁会导致未定义的行为?
根据http://www.cplusplus.com/reference/mutex/mutex/unlock/,例如,如果线程1锁定了一个互斥锁,然后线程2然后尝试在未锁定该互斥锁之前对其进行了解锁,则我们将产生未定义的行为。
答案 0 :(得分:1)
在成员函数unlock()
上查看此文档,该函数是要链接其文档的成员函数:
https://en.cppreference.com/w/cpp/thread/mutex/unlock
它说明:
std :: mutex :: unlock()
解锁互斥锁。
互斥锁必须由当前执行线程锁定, 否则,行为是不确定的。
因此,我认为文档只是指出,如果线程试图解锁它不拥有的互斥锁,则会导致未定义的行为。
关于问题标题的问题:锁定另一个线程拥有的锁是一个明确定义的行为(这就是为什么我们拥有std::mutex
)https://en.cppreference.com/w/cpp/thread/mutex/lock:
std :: mutex :: lock()
锁定互斥锁。如果另一个线程已经锁定了互斥锁,则 调用锁将阻止执行,直到获得锁为止。
请注意,直接解锁互斥锁通常不是一个好主意,您应该使用std::lock_guard
之类的RAII包装器
答案 1 :(得分:1)
您提供的链接实际上是关于双重解锁,而不是双重锁定。 但是,该操作(即从其他线程解锁互斥锁,而所有者线程未锁定互斥锁)是UB,因为该语言未定义应如何实现互斥锁,因此(这纯粹是推测)启用了二进制锁,哪个双重解锁实际上可能会锁定...
答案 2 :(得分:0)
根据http://www.cplusplus.com/reference/mutex/mutex/unlock/:
互斥锁上的所有锁定和解锁操作都遵循一个总顺序,所有可见效果在锁定操作和同一对象的先前解锁操作之间同步。 如果互斥锁当前未被调用线程锁定,则会导致未定义的行为。
这只是意味着您应该始终(在同一线程中)在解锁之前调用锁定。