【Muduo源码剖析笔记】Muduo Base库结构简介

【Muduo源码剖析笔记】Muduo Base库结构简介

作为第一次阅读源码的新手,感觉Muduo库的结构和代码都还是相对其他源码清晰和简单的。Base库包含了实现网络库所需的基础组件,但是自己第一次读的时候,在各个头文件的依赖关系中绕来绕去走了一些弯路,因此笔记以源代码中,头文件和实现文件为一个编译模块为单位梳理一下Base库的结构组成。

Base库的组件有多种类型,有的组件自己实现了单一功能,比如noncopyable模块可以为其他组件提供不可复制的tag提示。有的多个组件结合在一起实现了一个功能,比如用于管理线程相关的组件。笔记尝试将组件分为以下几类:

全局函数变量组件:定义了一些在不同命名空间下的函数和变量,供其他所有的组件调用。有时候这些函数变量也会出现在其他模块中。

功能组件:特别指提供与网络库没有直接相关的功能模块,更多的是与提供与编程角度相关的功能。

结构组件:提供与网络库相关的功能模块,可供其他模块调用,是整个网络库的组成部分之一。

个人阅读源码学习顺序可以从功能组件到结构组件,从基础到比较上层的功能顺序阅读。

各个组件的详细功能笔记后续再整理发出,这里只对模块的功能进行简介。

全局函数组件

CurrentThread

其并未定义新的类,定义了在CurrentThread命名空间里的线程相关的全局函数。这些函数主要供子线程管理自己的线程相关数据信息。

Types

定义了类型转换的两个函数和一个将一片内存置零的函数。

ProcessInfo

封装了线程相关的一些函数,和读取系统文件的一些函数。

功能组件

noncopyable(copyable)

定义了noncopyable类,属于一个tag类,可以供其他任何class继承,表示类不可以调用拷贝构造函数和赋值构造函数,这两个函数都使用C++11的delete关键字删除掉了。

copyable同理。

Atomic.h

定义了模板类AtomicIntegerT,提供其他文件使用AtomicIntegerT<int32_t> AtomicInt32和:AtomicIntegerT<int64_t> AtomicInt64。该类内部包含一个类型为模板类T的value_数据成员,封装了与之相关的操作函数,比如获得该数,自加等操作。其使用了GCC内置的原子操作实现,因此是原子级别的。

StringPiece

定义了两个类,一个为StringArg,内部包含一个const char* str_数据成员,属于C风格表示的字符串,这个类常用于作为函数的参数,由于其定义了两个初始化函数,即可以使用const char*初始化,也可以用const string&初始化。

另一个StringPiece类,其也是表示一个const char*的字符串,内部包含一个const char *类型指针和int类型的length_数据成员,同时封装了与之相关的操作函数。其目的是为了节省string的拷贝开销。

// You can use StringPiece as a function or method parameter. A StringPiece
// parameter can receive a double-quoted string literal argument, a “const
// char*” argument, a string argument, or a StringPiece argument with no data
// copying. Systematic use of StringPiece for arguments reduces data
// copies and strlen() calls.

Exception

定义了Exception类,包含两个string类型的数据成员用于保存异常的相关信息。

Timestamp

顾名思义定义了时间戳的类。

TimeZone

封装了时间区相关的类(还没阅读,有点繁琐)

结构组件

同步原语

包含mutex、Condition和CountDownLatch。管理互斥锁,条件变量和基于互斥锁、条件变量实现的CountDownLatch。基于RAII的思想管理这些系统资源。

FileUtil

封装了一个名为AppendFile的类,包含一个文件描述符,来管理这个文件资源。

日志库

按照自下而上的顺序,包含Logstream、Logging、AsyncLogging、LogFile。整个流程是,LogStream封装了一块内存空间以及对此相关操作的函数。Logging定义了一个Logger类,其封装了对相关操作函数的调用逻辑,其被其他需要输出日志信息的子线程调用,把日志信息放在自己的buffer后,再把这个结果通过一个全局输出函数g_output输出到AsyncLogging类的Buffer中。AsyncLogging类位于主线程区,保存两个Buffer来缓冲日志数据。然后日志线程会运行AsyncLogging类中定义的线程函数,在日志线程中分配两个区来获取主线程中的日志数据,然后通过自己定义的一个局部变量LogFile,通过LogFile实现IO读取完成日志记录。

任务队列

BlockingQueue和BoundedBlockingQueue。实现阻塞式的队列获取,都是模板类,模板类型就是你想放进队列中的数据类型。比如线程池就会把任务(函数指针)放入队列中。Bounded的队列是有界的,BlockingQueue可以无限往里面塞。

线程相关

Thread中定义了Thread类,其通常由主线程创建,包含与线程相关的信息,比如线程的id,运行的函数指针地址等等,和与线程操作相关的函数比如让其开始执行。用于主线程管理子线程的创建与销毁。

ThreadLocal和ThreadLocalSingleton都能帮你获取一份各个子线程独有的一份线程特有数据,区别是否是单例而已。

ThreadPool实现了线程池的创建和管理,其中会使用到任务队列,让创建的线程都去争抢队列中的任务。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值