多线程实践
说明:factory里面保存者对象,对象用ID标识,当相同I/D请求则把当前对象池对象返回,如果对象不被任何地方使用对象要被析构
template<typename T>
class FastFactory {
public:
shared_ptr<T> get(string id) {
unique_lock<mutex> lock(m_mutex_);
shared_ptr<T> ptr = m_list_[id];
if (!ptr) {
ptr = make_shared<T>(id);
}
return ptr;
}
private:
mutex m_mutex_;
unordered_map<string, shared_ptr<T> > m_list_;
};
问题所在:
unordered_map保存的shared_ptr永远不会析构一直强引用绑着,我们需要如果对象不被任何地方使用对象要被析构
? 用锁因为这里已经出现了共享变量的读取以及竟态条件的判断
template<typename T>
class FastFactory {
public:
shared_ptr<T> get(string id) {
unique_lock<mutex> lock(m_mutex_);
weak_ptr<T>& ptr = m_list_[id]; //
shared_ptr<T> ret = ptr.lock();
if (!ret) {
ret = make_shared<T>(id);
ptr = ret;
}
return ret;
}
private:
mutex m_mutex_;
unordered_map<string, weak_ptr<T> > m_list_;
};
说明:解决了版本1不释放的问题
问题所在:
? 但是unordered_map这个list的size没有减少,因为只要有新ID size就会增加,这就不对了
class Test {
public:
Test(string id) :
m_id(id) {
}
const string& key() const { return m_id; }
private:
string m_id;
};
template<typename T>
class FastFactory {
public:
shared_ptr<T> get(string id) {
unique_lock<mutex> lock(m_mutex_);
weak_ptr<T>& ptr = m_list_[id]; //
shared_ptr<T> ret = ptr.lock();
if (!ret) {
ret.reset(new T(id), bind(&FastFactory::deleteObject, this, std::placeholders::_1));
ptr = ret;
}
return ret;
}
private:
void deleteObject(T* ptr) {
if (ptr) {
unique_lock<mutex> lock(m_mutex_);
m_list_.erase(ptr->key());
}
delete ptr;
}
typedef function<void(T*)> functor;
mutex m_mutex_;
unordered_map<string, weak_ptr<T> > m_list_;
};
说明:使用deleteObject来进行 对象池的移除
问题:bind使用this进行绑定,存在可能性对象池销毁了,造成异常
class Test {
public:
Test(string id) :
m_id(id) {
}
const string& key() const { return m_id; }
private:
string m_id;
};
template<typename T>
class FastFactory : public enable_shared_from_this<FastFactory<T> >{
public:
shared_ptr<T> get(string id) {
unique_lock<mutex> lock(m_mutex_);
weak_ptr<T>& ptr = m_list_[id]; //
shared_ptr<T> ret = ptr.lock();
if (!ret) {
ret.reset(new T(id), bind(&FastFactory::deleteObject, this->shared_from_this(), std::placeholders::_1));
ptr = ret;
}
return ret;
}
private:
void deleteObject(T* ptr) {
if (ptr) {
unique_lock<mutex> lock(m_mutex_);
m_list_.erase(ptr->key());
}
delete ptr;
}
typedef function<void(T*)> functor;
mutex m_mutex_;
unordered_map<string, weak_ptr<T> > m_list_;
};
说明:加入enable_shared_from_this让类shared_ptr给外部
问题:这延长了FastFactory的生命周期
如果对象活着就调用,使用weak_ptr
class Test {
public:
Test(string id) :
m_id(id) {
std::cout << "Test() id = " << m_id << std::endl;
}
~Test()
{
std::cout << "~Test() id = " << m_id << std::endl;
}
const string& key() const { return m_id; }
private:
string m_id;
};
template<typename T>
class FastFactory : public enable_shared_from_this<FastFactory<T> >{
public:
shared_ptr<T> get(string id) {
unique_lock<mutex> lock(m_mutex_);
weak_ptr<T>& ptr = m_list_[id]; //
shared_ptr<T> ret = ptr.lock();
if (!ret) {
ret.reset(new T(id), bind(&FastFactory::deleteObject, this->shared_from_this(), std::placeholders::_1));
ptr = ret;
}
return ret;
}
private:
static void deleteObject(const weak_ptr<FastFactory<T> >& weak_factory, T* ptr) {
shared_ptr<FastFactory<T> > factory = weak_factory.lock();
if (ptr) {
factory->removePtr(ptr);
}
}
void removePtr(T* ptr) {
if (ptr) {
unique_lock<mutex> lock(m_mutex_);
auto key = m_list_.find(ptr->key());
if ( (key != m_list_.end()) && (key->second.expired()) ) {
m_list_.erase(ptr->key());
}
}
delete ptr;
}
typedef function<void(T*)> functor;
mutex m_mutex_;
unordered_map<string, weak_ptr<T> > m_list_;
};
说明:使用静态deleteObject,作为bind的显示参数,之后内部调用removePtr来进行析构
这样 对象池和被创建的对象就互相不是强绑定的依赖了
原文:https://www.cnblogs.com/chaohacker/p/14942474.html