EventLoop,TcpClient,TcpServer 中的生命周期
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 中去除。
- Golang标准库学习——buffio包 ---转
- 【Go 语言社区】Go语言条件变量的两个例子
- mysqlimport导入报错的排查(r10笔记第58天)
- 【Go 语言社区】POJ 1047 Round and Round We Go 循环数新解
- 【Go 语言社区】删除redis所有KEY
- 【Go 语言社区】Golang 动态实例化结构体
- 【Go 语言社区】Go 错误处理
- 【Go 语言社区】Go 语言范围(Range)
- 【Go 语言社区】JS 相关---Window Location
- 【Go 语言社区】Go 语言Map(集合)
- 【Go 语言社区】JavaScript Date(日期)对象
- UWP基础教程 - XAML类型转换器
- Oracle 12c Data Guard搭建(一) (r10笔记第57天)
- 【Go 语言社区】Go语言 Cookie的使用
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- [Web] CSS 中 Display(显示) 与 Visibility(可见性)的区别与用法
- [数据结构] 二叉搜索树的CURD(增删改查)操作
- Python 为什么用 # 号作注释符?
- Logging with ElasticSearch, Kibana, ASP.NET Core and Docker
- 【DB笔试面试843】在Oracle中,解释GLOBAL_NAMES设为TRUE的用途。
- SpringBoot 返回 json 数据以及数据封装(万字长文)
- 内核级木马与病毒攻防:Linux可执行文件的ELF格式描述
- 「 思考 」 React Hooks 的设计哲学
- JMeter之Json提取器详解
- nodejs 图片处理工具 gm 的使用!
- Java 进程内存分布
- Web 游戏监听浏览器返回点击事件 !
- 权限维持_Linux操作系统后门
- Linux入门学习笔记(一)
- CMD命令笔记总结