muduo 中,大量是用 smart point 省掉自己管理内存.下面开着源码参看。
question 1:EventLoop 的生命周期
answer 1: 建立在栈中,离开范围以后,自动释放。
void EventLoopThread::threadFunc()
{
EventLoop loop;//这里声明了本地epoller,也就是线程当地的epoller
if (callback_)
{
callback_(&loop);
}
{
MutexLockGuard lock(mutex_);
// 一般情况是EventLoopThread对象先析构,析构函数调用loop_->quit() 使得loop.loop() 退出循环
// 这样threadFunc 退出,loop栈上对象析构,loop_ 指针失效,但此时已经不会再通过loop_ 访问loop,
// 故不会有问题。
loop_ = &loop;
cond_.notify();
}
loop.loop();
//assert(exiting_);
loop_ = NULL;
}
question 2:EventLoop 有什么含指针类成员?
answer 2: (1) vector< Channel *> attiveChannels_; 只是存放,不管理里面的 Channel 死活.
(2) scoped_ptr<Poller> poller_; => 自动析构
(3) scoped_ptr<TimerQueue> timeQueue; => 自动析构
(4) scoped_ptr<Channel> wakeripChannel_; 自动析构
得:EventLoop 掌管着 2,3,4 的生命
question 3: TcpClient 的生命周期?
answer 3:一般在栈上,跟程序差不多。
question 4: TcpClient 有什么含指针的成员?
answer 4: (1) shared_ptr<Connector> ConnectorPtr connector_; =>自动析构
(2) shared_ptr<TcpConnection> TcpConnectionPtr connection_; =>自动析构
当
TcpClient::~TcpClient()
{
LOG_INFO << "TcpClient::~TcpClient[" << name_
<< "] - connector " << get_pointer(connector_);
TcpConnectionPtr conn;
{
MutexLockGuard lock(mutex_);
conn = connection_;
}
// 你这里什么情况下 conn 会为空啊,未连接的时候
if (conn)
{
// FIXME: not 100% safe, if we are in different thread
CloseCallback cb = boost::bind(&detail::removeConnection, loop_, _1);
loop_->runInLoop(
boost::bind(&TcpConnection::setCloseCallback, conn, cb));
}
else
{
connector_->stop();//关闭连接器
// FIXME: HACK
loop_->runAfter(1, boost::bind(&detail::removeConnector, connector_));//connector会自己在Tcpclient之后析构
}
}
question 5: TcpConnection 的生命周期
answer 5:两种情况,(1)对方断开连接;(2)自己退出;
(1)当遇到别人断开连接 => channel_->handleEvent() -> connection_->handleClose();
handleClose(){ 设置状态为非链接 => 清空事件
=> 新建一个 TcpConnectionPtr 对象,预防被析构。
=> 调用 connectionCallback() 告诉用户
=> 调用 closeCallback() => removeConnection()
}
removeConnection{ 将 TcpClient 中的 connectoin_ 置空,假如 handleClose() 不新建,这里就析构了
,然后后面调用 TcpConnection::connectDestroyed 就会失败
}
connectiDestroyed{ 将 channel_ 从 poller_ 中删除 }
最后,回到 handleClose() ,TcpConnectionPtr 析构掉,带有的 Socket, Channel 也就析构掉了。
(2) 当自己退出的话,就直接从connectDestory()开始执行.
详情,参照源码看。
然后,TcpServer 的话,跟 TcpClient 比,多了个map<string,TcpConnectionPtr> connections_;
处理断开的话,就多了一个,从 map 中去除。