线程安全的对象生命期管理(七)

本文探讨了使用对象池模式管理Stock对象的实例,通过从shared_ptr到weak_ptr的转换解决了对象永生问题,并进一步利用shared_ptr的定制析构功能优化内存管理,确保map中的条目在对象销毁时得到清理。

对象池

        举例:

class StockFactory : boost::noncopyable
{
public:
	shared_ptr<Stock> get(const string& key);
private:
	mutable MutexLock mutex;
	std::map<string,shared_ptr<Stock> > stock;
};

        这段代码中有一个问题,Stock对象永远不会被销毁,因为map里存的是shared_ptr,那就改为weak_ptr:

        

class StockFactory : boost::noncopyable
{
public:
	shared_ptr<Stock> get(const string& key);
private:
	mutable MutexLock mutex;
	std::map<string,weak_ptr<Stock> > stocks;
};

shared_ptr<Stock> StockFactory::get(const string& key)
{
	shared_ptr<Stock> pStock;
	MutexLockGuard lock(mutex);
	weak_ptr<Stock>& wkStock = stocks[key];
	pStock = wkStock.lock();
	if(!pStock)
	{
		pStock.reset(new Stock(key));
		wkStock = pStock;
	}
	return pStock;
}

                解决了对象不销毁的问题,但是程序有轻微的内存泄漏,因为map大小只增不减。

                针对这个问题,可以利用shared_ptr的定制析构功能。shared_ptr的额外模板类型参数可以传入一个函数指针或仿函数,在析构时就可以执行该函数来达到目的。

               

template<class Y,class D>shared_ptr::shared_ptr(Y* p,D d);
template<class Y,class D>shared_ptr::reset(Y* p,D d);

class StockFactory : boost::noncopyable
{
public:
	shared_ptr<Stock> get(const string& key);
private:
	mutable MutexLock mutex;
	std::map<string,weak_ptr<Stock> > stocks;
	void deleteStock(Stock* stock)
	{
		if(stock)
		{
			MutexLockGuard lock(mutex);
			stocks.erase(stock->key());
		}
		delete stock;
	}
};

shared_ptr<Stock> StockFactory::get(const string& key)
{
	shared_ptr<Stock> pStock;
	MutexLockGuard lock(mutex);
	weak_ptr<Stock>& wkStock = stocks[key];
	pStock = wkStock.lock();
	if(!pStock)
	{
		pStock.reset(new Stock(key),boost::bind(&StockFactory::deleteStock,this,l));
		wkStock = pStock;
	}
	return pStock;
}

              这样就做到了在析构Stock对象的同时将对应的map中的变量也删除。这里暴露了this指针会有线程安全问题,在后面解决。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值