我正在尝试使用递归类,我阅读了QMutex类参考,但我不知道如何做到这一点,有人能给我一个例子吗?我需要一些方法来锁定可以在调用QMutex方法之后或之前解锁的锁。如果递归互斥不是方法,还有其他方法吗?
发布于 2012-12-01 05:14:58
要创建递归QMutex,只需在构造时传递QMutex::Recursive,例如:
QMutex mutex(QMutex::Recursive);
int number = 6;
void method1()
{
mutex.lock();
number *= 5;
mutex.unlock();
}
void method2()
{
mutex.lock();
number *= 3;
mutex.unlock();
}Recursive意味着您可以多次锁定来自同一线程的互斥锁,而不必解锁它。如果我很理解你的问题,那就是你想要的。
请注意,如果您以递归方式锁定,则必须调用相同的unlock次数。锁定/解锁互斥锁的更好方法是使用QMutexLocker
#include <QMutexLocker>
QMutex mutex(QMutex::Recursive);
int number = 6;
void method1()
{
QMutexLocker locker(&mutex); // Here mutex is locked
number *= 5;
// Here locker goes out of scope.
// When locker is destroyed automatically unlocks mutex
}
void method2()
{
QMutexLocker locker(&mutex);
number *= 3;
}发布于 2014-03-11 04:20:29
递归互斥锁可以从单个线程多次锁定,而不需要解锁,只要从同一线程进行相同数量的解锁调用即可。当一个共享资源被多个函数使用,并且其中一个函数调用另一个使用该资源的函数时,这种机制就派上用场了。
考虑下面的类:
class Foo {
public:
Foo();
void bar(); // Does something to the resource
void thud(); // Calls bar() then does something else to the resource
private:
Resource mRes;
QMutex mLock;
}初始实现可能如下所示:
Foo::Foo() {}
void Foo::bar() {
QMutexLocker locker(&mLock);
mRes.doSomething();
}
void Foo::thud() {
QMutexLocker locker(&mLock);
bar();
mRes.doSomethingElse();
}上面的代码会在调用thud时死锁。mLock将在thud()的第一行中获取,并再次被bar()的第一行获取,这将阻塞等待thud()释放锁。
一个简单的解决方案是使锁在ctor中递归。
Foo::Foo() : mLock(QMutex::Recursive) {}这是一个OK修复,适用于许多情况,但是应该意识到使用此解决方案可能会有性能损失,因为每个递归互斥调用可能需要一个系统调用来标识当前线程id。
除了线程id检查之外,对thud()的所有调用仍然执行QMutex::lock()两次!
需要递归的设计可以通过重构来消除对递归互斥的需求。一般来说,对递归互斥锁的需求是一种“代码气味”,表明需要坚持关注点分离的原则。
对于类Foo,可以想象创建一个私有函数调用来执行共享计算,并在公共接口级别保持资源锁定。
class Foo {
public:
Foo();
void bar(); // Does something to the resource
void thud(); // Does something then does something else to the resource
private:
void doSomething();
private:
Resource mRes;
QMutex mLock;
}
Foo::Foo() {}
// public
void Foo::bar() {
QMutexLocker locker(&mLock);
doSomething();
}
void Foo::thud() {
QMutexLocker locker(&mLock);
doSomething();
mRes.doSomethingElse();
}
// private
void Foo::doSomething() {
mRes.doSomething(); // Notice - no mutex in private function
}发布于 2012-11-30 09:54:17
递归模式只是意味着,如果一个线程拥有一个互斥锁,而同一个线程再次尝试锁定该互斥锁,那么它将会成功。要求是对lock/unlock的调用是平衡的。
在非递归模式下,这将导致死锁。
https://stackoverflow.com/questions/13637830
复制相似问题