求真百科歡迎當事人提供第一手真實資料,洗刷冤屈,終結網路霸凌。

Linux多线程服务端编程查看源代码讨论查看历史

跳转至: 导航搜索

来自 孔夫子网 的图片

Linux多线程服务端编程》,副标题:使用muduo C++网络库,陈硕 著,出版社: 电子工业出版社。

电子工业出版社成立于1982年10月,是工业和信息化部直属的科技与教育出版社,每年出版新书2400余种,音像和电子出版物400余种,期刊8种,出版物内容涵盖了信息科技的各个专业分支以及工业技术、经济管理、大众生活、少儿科普[1]等领域,综合出版能力位居全国出版行业前列[2]

内容简介

本书主要讲述采用现代C++在x86-64Linux上编写多线程TCP网络服务程序的主流常规技术,重点讲解一种适应性较强的多线程服务器的编程模型,即one loop per thread。这是在Linux下以native语言编写用户态高性能网络程序成熟的模式,掌握之后可顺利地开发各类常见的服务端网络应用程序。本书以muduo网络库为例,讲解这种编程模型的使用方法及注意事项。本书的宗旨是贵精不贵多。掌握两种基本的同步原语就可以满足各种多线程同步的功能需求,还能写出更易用的同步设施。掌握一种进程间通信方式和一种多线程网络编程模型就足以应对日常开发任务,编写运行于公司内网环境的分布式服务系统。

目录

第1部分 C++多线程系统编程

第1章 线程安全的对象生命期管理

1.1 当析构函数遇到多线程

1.1.1 线程安全的定义

1.1.2 texLock与 texLockGuard

1.1.3 一个线程安全的Counter示例

1.2 对象的创建很简单

1.3 销毁太难

1.3.1 mutex不是办法

1.3.2 作为数据成员的mutex不能保护析构

1.4 线程安全的Observer有多难

1.5 原始指针有何不妥

1.6 利器shared_ptr/weak_ptr

1.7 插曲:系统地避免各种指针错误

1.8 应用到Observer上

1.9 再论shared_ptr的线程安全

1.10 shared_ptr技术与陷阱

1.11 对象池

1.11.1 enable_shared_from_this

1.11.2 弱回调

1.12 替代方案

1.13 心得与小结

1.14 Observer之谬

第2章 线程同步精要

2.1 互斥器(mutex)

2.1.1 只使用非递归的mutex

2.1.2 死锁

2.2 条件变量(condition variable)

2.3 不要用读写锁和信号量

2.4 封装 texLock、 texLockGuard、Condition

2.5 线程安全的Singleton实现

2.6 sleep(3)不是同步原语

2.7 归纳与总结

2.8 借shared_ptr实现copy-on-write

第3章 多线程服务器的适用场合与常用编程模型

3.1 进程与线程

3.2 单线程服务器的常用编程模型

3.3 多线程服务器的常用编程模型

3.3.1 one loop per thread

3.3.2 线程池

3.3.3 推荐模式

3.4 进程间通信只用TCP

3.5 多线程服务器的适用场合

3.5.1 必须用单线程的场合

3.5.2 单线程程序的优缺点

3.5.3 适用多线程程序的场景

3.6 “多线程服务器的适用场合”例释与答疑

第4章 C++多线程系统编程精要

4.1 基本线程原语的选用

4.2 C/C++系统库的线程安全性

4.3 Linux上的线程标识

4.4 线程的创建与销毁的守则

4.4.1 pthread_cancel与C++

4.4.2 exit(3)在C++中不是线程安全的

4.5 善用_thread关键字

4.6 多线程与IO

4.7 用RAII包装文件描述符

4.8 RAII与fork()

4.9 多线程与fork()

4.10 多线程与signal

4.11 Linux新增系统调用的启示

第5章 高效的多线程日志

5.1 功能需求

5.2 性能需求

5.3 多线程异步日志

5.4 其他方案

第2部分 muduo网络库

第6章 muduo网络库简介

6.1 由来

6.2 安装

6.3 目录结构

6.3.1 代码结构

6.3.2 例子

6.3.3 线程模型

6.4 使用教程

6.4.1 TCP网络编程本质论

6.4.2 echo服务的实现

6.4.3 七步实现finger服务

6.5 性能评测

6.5.1 muduo与Boost.Asio、libevent2的吞吐量对比

6.5.2 击鼓传花:对比muduo 与libevent2的事件处理效率

6.5.3 muduo与Nginx的吞吐量对比

6.5.4 muduo与ZeroMQ的延迟对比

6.6 详解muduo多线程模型

6.6.1 数独求解服务器

6.6.2 常见的并发网络服务程序设计方案

第7章 muduo编程示例

7.1 五个简单TCP示例

7.2 文件传输

7.3 Boost.Asio的聊天服务器

7.3.1 TCP分包

7.3.2 消息格式

7.3.3 编解码器LengthHeaderCodec

7.3.4 服务端的实现

7.3.5 客户端的实现

7.4 muduo Buffer类的设计与使用

7.4.1 muduo的IO模型

7.4.2 为什么non-blocking网络编程中应用层buffer是必需的

7.4.3 Buffer的功能需求

7.4.4 Buffer的数据结构

7.4.5 Buffer的操作

7.4.6 其他设计方案

7.4.7 性能是不是问题

7.5 一种自动反射消息类型的Google Protobuf网络传输方案

7.5.1 网络编程中使用Protobuf的两个先决条件

7.5.2 根据type name反射自动创建Message对象

7.5.3 Protobuf传输格式

7.6 在muduo中实现Protobuf编解码器与消息分发器

7.6.1 什么是编解码器(codec)

7.6.2 实现ProtobufCodec

7.6.3 消息分发器(dispatcher)有什么用

7.6.4 ProtobufCodec与ProtobufDispatcher的综合运用

7.6.5 ProtobufDispatcher的两种实现

7.6.6 ProtobufCodec和ProtobufDispatcher有何意义

7.7 服务器的优选并发连接数

7.7.1 为什么要并发连接数

7.7.2 在muduo中并发连接数

7.8 定时器

7.8.1 程序中的时间

7.8.2 Linux时间函数

7.8.3 muduo的定时器接口

7.8.4 Boost.Asio Timer示例

7.8.5 Java Netty示例

7.9 测量两台机器的网络延迟和时间差

7.10 用timing wheel踢掉空闲连接

7.10.1 timing wheel原理

7.10.2 代码实现与改进

7.11 简单的消息广播服务

7.12 “串并转换”连接服务器及其自动化测试

7.13 socks4a代理服务器

7.13.1 TCP中继器

7.13.2 socks4a代理服务器

7.13.3 N:1与1:N连接转发

7.14 短址服务

7.15 与其他库集成

7.15.1 UDNS

7.15.2 c-ares DNS

7.15.3 curl

7.15.4 更多

第8章 muduo网络库设计与实现

8.0 什么都不做的EventLoop

8.1 Reactor的关键结构

8.1.1 Channel class

8.1.2 Poller class

8.1.3 EventLoop的改动

8.2 TimerQueue定时器

8.2.1 TimerQueue class

8.2.2 EventLoop的改动

8.3 EventLoop::runInLoop()函数

8.3.1 提高TimerQueue的线程安全性

8.3.2 EventLoopThread class

8.4 实现TCP网络库

8.5 TcpServer接受新连接

8.5.1 TcpServer class

8.5.2 TcpConnection class

8.6 TcpConnection断开连接

8.7 Buffer读取数据

8.7.1 TcpConnection使用Buffer作为输入缓冲

8.7.2 Buffer::readFd()

8.8 TcpConnection发送数据

8.9 完善TcpConnection

8.9.1 SIGPIPE

8.9.2 TCP No Delay和TCP keepalive

8.9.3 WriteCompleteCallback和HighWaterMarkCallback

8.10 多线程TcpServer

8.11 Connector

8.12 TcpClient

8.13 epoll

8.14 测试程序一览

第3部分 工程实践经验谈

第9章 分布式系统工程实践

9.1 我们在技术浪潮中的位置

9.1.1 分布式系统的本质困难

9.1.2 分布式系统是个险恶的问题

9.2 分布式系统的可靠性浅说

9.2.1 分布式系统的软件不要求7×24可靠

9.2.2 “能随时重启进程”作为程序设计目标

9.3 分布式系统中心跳协议的设计

9.4 分布式系统中的进程标识

9.4.1 错误做法

9.4.2 正确做法

9.4.3 TCP协议的启示

9.5 构建易于维护的分布式程序

9.6 为系统演化做准备

9.6.1 可扩展的消息格式

9.6.2 反面教材:ICE的消息打包格式

9.7 分布式程序的自动化回归测试

9.7.1 单元测试的能与不能

9.7.2 分布式系统测试的要点

9.7.3 分布式系统的抽象观点

9.7.4 一种自动化的回归测试方案

9.7.5 其他用处

9.8 分布式系统部署、监控与进程管理的几重境界

9.8.1 境界1:全手工操作

9.8.2 境界2:使用零散的自动化脚本和第三方组件

9.8.3 境界3:自制机群管理系统,集中化配置

9.8.4 境界4:机群管理与naming service结合

第10章 C++编译链接模型精要

10.1 C 语言的编译模型及其成因

10.1.1 为什么C语言需要预处理

10.1.2 C语言的编译模型

10.2 C++的编译模型

10.2.1 单遍编译

10.2.2 前向声明

10.3 C++链接(linking)

10.3.1 函数重载

10.3.2 inline函数

10.3.3 模板

10.3.4 虚函数

10.4 工程项目中头文件的使用规则

10.4.1 头文件的害处

10.4.2 头文件的使用规则

10.5 工程项目中库文件的组织原则

10.5.1 动态库是有害的

10.5.2 静态库也好不到哪儿去

10.5.3 源码编译是王道

第11章 反思C++面向对象与虚函数

11.1 朴实的C++设计

11.2 程序库的二进制兼容性

11.2.1 什么是二进制兼容性

11.2.2 有哪些情况会破坏库的ABI

11.2.3 哪些做法多半是安全的

11.2.4 反面教材:COM

11.2.5 解决办法

11.3 避免使用虚函数作为库的接口

11.3.1 C++程序库的作者的生存环境

11.3.2 虚函数作为库的接口的两大用途

11.3.3 虚函数作为接口的弊端

11.3.4 假如Linux系统调用以COM接口方式实现

11.3.5 Java是如何应对的

11.4 动态库接口的推荐做法

11.5 以boost::function 和boost::bind 取代虚函数

11.5.1 基本用途

11.5.2 对程序库的影响

11.5.3 对面向对象程序设计的影响

11.6 iostream的用途与局限

11.6.1 stdio格式化输入输出的缺点

11.6.2 iostream的设计初衷

11.6.3 iostream与标准库其他组件的交互

11.6.4 iostream在使用方面的缺点

11.6.5 iostream在设计方面的缺点

11.6.6 一个300行的memory buffer output stream

11.6.7 现实的C++程序如何做文件IO

11.7 值语义与数据抽象

11.7.1 什么是值语义

11.7.2 值语义与生命期

11.7.3 值语义与标准库

11.7.4 值语义与C++语言

11.7.5 什么是数据抽象

11.7.6 数据抽象所需的语言设施

11.7.7 数据抽象的例子

第12章 C++经验谈

12.1 用异或来交换变量是错误的

12.1.1 编译器会分别生成什么代码

12.1.2 为什么短的代码不一定快

12.2 不要重载全局::operator new()

12.2.1 内存管理的基本要求

12.2.2 重载::operator new()的理由

12.2.3 ::operator new()的两种重载方式

12.2.4 现实的开发环境

12.2.5 重载::operator new()的困境

12.2.6 解决办法:替换malloc()

12.2.7 为单独的class重载::operator new()有问题吗

12.2.8 有必要自行定制内存分配器吗

12.3 带符号整数的除法与余数

12.3.1 语言标准怎么说

12.3.2 C/C++编译器的表现

12.3.3 其他语言的规定

12.3.4 脚本语言解释器代码

12.3.5 硬件实现

12.4 在单元测试中mock系统调用

12.4.1 系统函数的依赖注入

12.4.2 链接期垫片(link seam)

12.5 慎用匿名namespace

12.5.1 C语言的static关键字的两种用法

12.5.2 C++语言的static关键字的四种用法

12.5.3 匿名namespace的不利之处

12.5.4 替代办法

12.6 采用有利于版本管理的代码格式

12.6.1 对diff友好的代码格式

12.6.2 对grep友好的代码风格

12.6.3 一切为了效率

12.7 再探std::string

12.7.1 直接拷贝(eager copy)

12.7.2 写时复制(copy-on-write)

12.7.3 短字符串优化(SSO)

12.8 用STL algorithm轻松解决几道算法面试题

12.8.1 用next_permutation()生成排列与组合

12.8.2 用unique()去除连续重复空白

12.8.3 用{make,push,pop}_heap()实现多路归并

12.8.4 用partition()实现“重排数组,让奇数位于偶数前面”

12.8.5 用lower_bound()查找IP地址所属的城市

第4部分 附录

附录A 谈一谈网络编程学习经验

附录B 从《C++ Primer(第4版)》入手学习C++

附录C 关于Boost的看法

附录D 关于TCP并发连接的几个思考题与试验

参考文献

参考文献

  1. 100部科普经典名著,豆瓣,2018-04-26
  2. 关于我们,电子工业出版社