boost asio 需要使用智能指针而不能使用普通指针的原因

当使用asio做服务器时,需要一个会话管理器来管理所有的会话,类似下面这样:

class SessionMgr
{
private:
	boost::shared_mutex _rw_mtx;
	
	boost::unordered_map<uint32, boost::shared_ptr<Session> > _session_list;
	boost::unordered_map<uint32, boost::shared_ptr<Session> >::iterator _iterator;
	
public:
	void AddSession(boost::shared_ptr<Session> session);
	void DelSession(boost::shared_ptr<Session> session);
	boost::shared_ptr<Session> GetSession(uint32 session_key);
	boost::shared_ptr<Session> GetFirstSession();
	boost::shared_ptr<Session> GetNextSession();
};

此类中使用会话指针时,不能直接用Session *来作为容器的元素,需要使用智能指针boost::shared_ptr<Session>来作为boost::unordered_map的元素,

原因是网络通信使用了异步机制,程序随时会把session对象的指针交给系统底层使用,由系统回调session对象的函数,比如:

void Session::HandleWrite(const boost::system::error_code &error)
{
	if(error)
	{
		cout << "[ERROR] func:" << __FUNCTION__ << ", error:" << error.value() << "," << error.message() << endl;
		
		DeleteSelf();
		return;
	}

	if(session_info.need_close)
	{
		return;
	}

	_socket.async_read_some(boost::asio::buffer(session_info.pkg_buf, MAX_SESSION_PKG_SIZE),
		boost::bind(&Session::HandleRead, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
}
在处理数据包写入完成时,会异步读取数据,将session对象自身的指针和函数HandleRead的地址传送给系统底层,系统读取成功时会自动回调这个成员函数。

如果是普通指针,那么会话管理器SessionMgr在删除会话时会立即释放掉Session对象,那么系统底层在回调成员函数时就会发生错误。

所以需要使用智能指针,在需要关闭会话时,只需要将Session指针从SessionMgr的容器中移除,不需要释放Session对象,再做一个标志表明会话需要删除就可以了。

在Session处理函数中判断标志,如果需要关闭的标志存在,则取消下一步的动作,比如,异步读取,异步写入等等,这样,Session指针的引用次数就不会再增加,当引用次数为0时,Session对象就会自动释放了。


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值