在陈硕的著作《Linux多线程服务端编程:使用muduo c++网络库》1.9节末,提出一个问题:如何在临界区以外销毁资源?
这里给出两个解法。二者只有两句话次序前后的区别,但是一个正确,一个错误。
目录
正确的解法
代码
#include <QCoreApplication>
#include <QMutex>
#include <memory>
#include <QDebug>
class CLock {
public:
QMutex m_mtx;
CLock(){m_mtx.lock();qDebug()<<"locked";}
~CLock(){m_mtx.unlock();qDebug()<<"unlocked";}
};
class Foo
{
public:
Foo(){qDebug()<<"constructing";}
~Foo(){qDebug()<<"destructing";}
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
auto spGlobal = std::make_shared<Foo>();
{
std::shared_ptr<Foo> spTemp;//栈的特点,先进后出
volatile CLock lok;
spTemp.swap(spGlobal);
}
return a.exec();
}
结果
可见是解锁以后才释放。
错误的解法
代码
#include <QCoreApplication>
#include <QMutex>
#include <memory>
#include <QDebug>
class CLock {
public:
QMutex m_mtx;
CLock(){m_mtx.lock();qDebug()<<"locked";}
~CLock(){m_mtx.unlock();qDebug()<<"unlocked";}
};
class Foo
{
public:
Foo(){qDebug()<<"constructing";}
~Foo(){qDebug()<<"destructing";}
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
auto spGlobal = std::make_shared<Foo>();
{
volatile CLock lok;//注意这里位置交换
std::shared_ptr<Foo> spTemp;//栈的特点,先进后出
spTemp.swap(spGlobal);
}
return a.exec();
}
结果
结论
lok和spTemp都是栈上的资源,所以满足先进后出的原则。正确的办法,先构造spTemp,所以释放spTemp就留到最后。反过来,先构造lok,lok解锁就放到最后。