当使用condition_variable_anya时recursive_mutex,通常recursive_mutex可以在等待时从其他线程获取吗?我对Boost和C++ 11实现感兴趣.condition_variable_any::wait
这是我主要关注的用例:
void bar();
boost::recursive_mutex mutex;
boost::condition_variable_any condvar;
void foo()
{
boost::lock_guard<boost::recursive_mutex> lock(mutex);
// Ownership level is now one
bar();
}
void bar()
{
boost::unique_lock<boost::recursive_mutex> lock(mutex);
// Ownership level is now two
condvar.wait(lock);
// Does this fully release the recursive mutex,
// so that other threads may acquire it while we're waiting?
// Will the recursive_mutex ownership level
// be restored to two after waiting?
}
Run Code Online (Sandbox Code Playgroud) 我在SO上读到这个答案:
因为递归互斥锁具有所有权感,所以抓取互斥锁的线程必须与释放互斥锁的线程相同.在非递归互斥锁的情况下,没有所有权感,任何线程通常都可以释放互斥锁,无论哪个线程最初使用互斥锁.
我对上一个陈述感到困惑.一个线程可以锁定一个互斥锁,另一个不同的线程可以解锁该互斥锁吗?我以为同一个线程应该是唯一能够解锁互斥锁的线程?或者是否有任何特定的互斥量允许这个?我希望有人能澄清一下.
我在下面的代码中遇到错误.
recursive_mutex m_RecurMutex;
condition_variable cond;
unique_lock<recursive_mutex> lock(m_RecurMutex);
cond.wait(lock); // Error Here.
Run Code Online (Sandbox Code Playgroud)
导致此错误的原因是什么?
我在程序中遇到了死锁的问题.所以我一直在阅读关于锁的问题,但问题是大多数信息是不一致的或不是平台定义的.在递归锁定(Mutex)与非递归锁定(Mutex)中,最常被接受的答案是:
由于递归互斥锁具有所有权感,因此获取互斥锁的线程必须与释放互斥锁的线程相同.在非递归互斥锁的情况下,没有所有权感,任何线程通常都可以释放互斥锁,无论哪个线程最初使用互斥锁.在许多情况下,这种类型的"互斥体"实际上更像是一种信号量动作,您不必将互斥体用作排除设备,而是将其用作两个或多个线程之间的同步或信号设备.
在评论中,人们说这是不正确的,没有关于它的参考.所以...
1)如果我在线程A中锁定非递归互斥锁.线程B可以解锁它而不需要锁定吗?
2)如果在线程A和线程B调用获取锁定的非递归互斥锁中的锁定中,线程B将等待直到锁定被释放以获得锁定还是会抛出异常?这个案例在递归互斥体中怎么样?(在其他问题中也讨论过,不能得出正确的结论)
3)当使用递归锁时,在进程终止时,是否必须释放所有递归锁?(取决于流程结束的地方,不会发生)
4)在谨慎使用递归锁和非递归锁的组合时,我看到了哪些问题?
PS:仅使用Windows平台和std::thread.
我想知道,当你移动会发生什么unique_lock是持有recursive_mutex。
具体来说,我在看这段代码:
recursive_mutex g_mutex;
#define TRACE(msg) trace(__FUNCTION__, msg)
void trace(const char* function, const char* message)
{
cout << std::this_thread::get_id() << "\t" << function << "\t" << message << endl;
}
future<void> foo()
{
unique_lock<recursive_mutex> lock(g_mutex);
TRACE("Owns lock");
auto f = std::async(launch::async, [lock = move(lock)]{
TRACE("Entry");
TRACE(lock.owns_lock()? "Owns lock!" : "Doesn't own lock!"); // Prints Owns lock!
this_thread::sleep_for(chrono::seconds(3));
});
TRACE(lock.owns_lock()? "Owns lock!" : "Doesn't own lock!"); // Prints Doesn't own lock!
return f;
}
int main()
{ …Run Code Online (Sandbox Code Playgroud) 据我了解,在 Windows 上 CRITICAL_SECTION 只能用作非递归互斥锁。要获得递归互斥锁,您必须使用 OpenMutex 和朋友。
但是,AFAIU、Win32 Mutex 不能与条件变量一起使用(InitializeConditionVariable 等)
有没有办法在 Windows 上将递归互斥体与条件变量结合使用?
在我的代码中,如果我的线程在调用 .ReleaseMutex() 之前多次调用 .WaitOne() 将会很方便。
反之亦然:在重新启动以调用 .WaitOne() 开始的循环之前,调用 .ReleaseMutex() 几次。
某些操作系统/编译器组合允许这样做。有些则不然。