1.TCP网络编程本质

TCP网络编程最本质是的处理三个半事件
(1)连接建立:服务器accept(被动)接受连接,客户端connect(主动)发起连接
(2)连接断开:主动断开(close、shutdown),被动断开(read返回0)
(3)消息到达:文件描述符可读
(4)消息发送完毕:这算半个。对于低流量的服务,可不必关心这个事件;这里的发送完毕是指数据写入操作系统缓冲区,将由TCP协议栈负责数据的发送与重传,不代表对方已经接收到数据。

2.什么都不做的EventLoop

(1)one loop   perthread意思是说每个线程最多只能有一个EventLoop对象。
(2)EventLoop对象构造的时候,会检查当前线程是否已经创建了其他EventLoop对象,如果已创建,终止程序(LOG_FATAL)
(3)EventLoop构造函数会记住本对象所属线程(threadId_)。
(4)创建了EventLoop对象的线程称为IO线程,其功能是运行事件循环(EventLoop::loop)

3.EchoServer类图

4.代码

POD类型,__thread t_loopInThisThreadl,每个线程都有一个。
EventLoop.h
// Copyright 2010, Shuo Chen.  All rights reserved.
// http://code.google.com/p/muduo/
//
// Use of this source code is governed by a BSD-style license
// that can be found in the License file.// Author: Shuo Chen (chenshuo at chenshuo dot com)
//
// This is a public header file, it must only include public header files.#ifndef MUDUO_NET_EVENTLOOP_H
#define MUDUO_NET_EVENTLOOP_H#include <boost/noncopyable.hpp>#include <muduo/base/CurrentThread.h>
#include <muduo/base/Thread.h>namespace muduo
{
namespace net
{///
/// Reactor, at most one per thread.
///
/// This is an interface class, so don't expose too much details.
class EventLoop : boost::noncopyable
{public:EventLoop();~EventLoop();  // force out-line dtor, for scoped_ptr members.////// Loops forever.////// Must be called in the same thread as creation of the object.///void loop();void assertInLoopThread(){if (!isInLoopThread()){abortNotInLoopThread();}}bool isInLoopThread() const { return threadId_ == CurrentThread::tid(); }static EventLoop* getEventLoopOfCurrentThread();private:void abortNotInLoopThread();bool looping_; /* atomic */const pid_t threadId_;     // 当前对象所属线程ID
};}
}
#endif  // MUDUO_NET_EVENTLOOP_H

EventLoop.c

// Copyright 2010, Shuo Chen.  All rights reserved.
// http://code.google.com/p/muduo/
//
// Use of this source code is governed by a BSD-style license
// that can be found in the License file.// Author: Shuo Chen (chenshuo at chenshuo dot com)#include <muduo/net/EventLoop.h>#include <muduo/base/Logging.h>#include <poll.h>using namespace muduo;
using namespace muduo::net;namespace
{
// 当前线程EventLoop对象指针
// 线程局部存储
__thread EventLoop* t_loopInThisThread = 0;
}EventLoop* EventLoop::getEventLoopOfCurrentThread()
{return t_loopInThisThread;
}EventLoop::EventLoop(): looping_(false),threadId_(CurrentThread::tid())
{LOG_TRACE << "EventLoop created " << this << " in thread " << threadId_;// 如果当前线程已经创建了EventLoop对象,终止(LOG_FATAL)if (t_loopInThisThread){LOG_FATAL << "Another EventLoop " << t_loopInThisThread<< " exists in this thread " << threadId_;}else{t_loopInThisThread = this;}
}EventLoop::~EventLoop()
{t_loopInThisThread = NULL;
}// 事件循环,该函数不能跨线程调用
// 只能在创建该对象的线程中调用
void EventLoop::loop()
{assert(!looping_);// 断言当前处于创建该对象的线程中assertInLoopThread();looping_ = true;LOG_TRACE << "EventLoop " << this << " start looping";::poll(NULL, 0, 5*1000);LOG_TRACE << "EventLoop " << this << " stop looping";looping_ = false;
}void EventLoop::abortNotInLoopThread()
{LOG_FATAL << "EventLoop::abortNotInLoopThread - EventLoop " << this<< " was created in threadId_ = " << threadId_<< ", current thread id = " <<  CurrentThread::tid();
}

Reactor_test01.cc

#include <muduo/net/EventLoop.h>#include <stdio.h>using namespace muduo;
using namespace muduo::net;void threadFunc()
{printf("threadFunc(): pid = %d, tid = %d\n",getpid(), CurrentThread::tid());EventLoop loop;loop.loop();
}int main(void)
{printf("main(): pid = %d, tid = %d\n",getpid(), CurrentThread::tid());EventLoop loop;Thread t(threadFunc);t.start();loop.loop();t.join();return 0;
}
运行结果

Reactor_02.cc

这个是一个错误的例子,t线程没有自己的EventLoop对象
#include <muduo/net/EventLoop.h>#include <stdio.h>using namespace muduo;
using namespace muduo::net;EventLoop* g_loop;void threadFunc()
{g_loop->loop();
}int main(void)
{EventLoop loop;g_loop = &loop;Thread t(threadFunc);t.start();t.join();return 0;
}

运行结果

25muduo_net库源码分析(一)相关推荐

  1. 《微信小程序-进阶篇》Lin-ui组件库源码分析-列表组件List(一)

    大家好,这是小程序系列的第二十篇文章,在这一个阶段,我们的目标是 由简单入手,逐渐的可以较为深入的了解组件化开发,从本文开始,将记录分享lin-ui的源码分析,期望通过对lin-ui源码的学习能加深组 ...

  2. Android主流三方库源码分析(九、深入理解EventBus源码)

    一.EventBus使用流程概念 1.Android事件发布/订阅框架 2.事件传递既可用于Android四大组件间通信 3.EventBus的优点是代码简洁,使用简单,事件发布.订阅充分解耦 4.首 ...

  3. sigslot库源码分析

    言归正传,sigslot是一个用标准C++语法实现的信号与槽机制的函数库,类型和线程安全.提到信号与槽机制,恐怕最容易想到的就是大名鼎鼎的Qt所支持的对象之间通信的模式吧.不过这里的信号与槽虽然在概念 ...

  4. surprise库源码分析

    最近工作上需要使用到协同过滤,来计算相似度,因此根据https://blog.csdn.net/weixin_43849063/article/details/111500236的步骤对surpris ...

  5. Python Requests库源码分析

    1. Requests库简介 书籍是人类进步的阶梯,源码是程序员进步的阶梯.为了进步,我们就要不断地阅读源码,提升自己的技术水平.今天我们来剖析一下Python的Requests库. Requests ...

  6. cJSON库源码分析

    cJSON是一个超轻巧,携带方便,单文件,简单的可以作为ANSI-C标准的Json格式解析库. 那什么是Json格式?这里照搬度娘百科的说法: Json(JavaScript Object Notat ...

  7. python库源码分析_python第三方库Faker源码解读

    源码背景 Faker是一个Python第三方库,GITHUB开源项目,主要用于创建伪数据创建的数据包含地理信息类.基础信息类.个人账户信息类.网络基础信息类.浏览器信息类.文件信息类.数字类 文本加密 ...

  8. 山东大学软件实验课程-Ebiten-基于go语言实现的2D游戏库源码分析第一篇-综述 2021SC@SDUSC

    2021SC@SDUSC 目录 一.项目综述 二.go语言安装及环境配置 1.Go的安装 2.IDE的使用 三.小组内成员分工 一.项目综述 Ebiten 是Go 编程语言的开源游戏库.Ebiten ...

  9. SoundTouch音频处理库源码分析及算法提取(1)

    SoundTouch音频处理库的使用异常简单,经过简单的编译之后,设置编译环境,以vc为例 ,直接在include包含SoundTouch目录下的include路径,接着在lib添加SoundTouc ...

最新文章

  1. SAP MM 采购附加费计入物料成本?
  2. 团队-象棋游戏-开发文档
  3. 狮子座2007年星座运程
  4. 服务器 kvm 进入系统,服务器CAT5 KVM切换器系统
  5. oracle查被锁存储过程,oracle 结束被锁的包或存储过程
  6. 宝塔服务器管理助手Linux面版-使用教程
  7. docker安装消息队列延时插件
  8. Apache双机热备
  9. 第一次申请去美国面签,需要注意哪些事项提高成功率?
  10. 自考《离散数学》题型总结
  11. 移动硬盘 计算机里不显示盘符,移动硬盘插在电脑上不显示盘符是怎么回事啊?...
  12. 射频加热原理及其参数
  13. 激光钎焊的主要工艺参数
  14. IDEA :插入代码模板(Ctrl+J )
  15. 计算机英语第五版翻译,计算机专业英语教程第5版翻译
  16. 关于银环蛇Z370主板的,M.2固态与SATA接口冲突的解决办法
  17. 【自动化】浅度分析自动化行业,深度好文!
  18. 在linux上配置Maven环境变量
  19. 数据是企业的上帝之眼,企业经营过程中如何正确的使用数据?
  20. Imply之HTTP推送

热门文章

  1. 思科:云技术正日趋普及 然而云战略并不成熟
  2. Beyond Compare 怎么新增与卸载文件格式
  3. PHP环境 PDOException PDOException: could not find driver
  4. 自动化运维工具puppet(四)
  5. window 2008 搭建的DHCP服务器
  6. Android系统进程Zygote启动过程的源代码分析(3)
  7. iOS(iPhone/iPad)开发新手必读
  8. linux chown命令: 修改文件或目录的所有者或群组
  9. C++0x 通用属性
  10. TinyXML2 入门教程