当前位置:首页 > 百科

Linux多线程服务端编程

来自Linux多线程服务端编程》是电子360百科工业出版社20父问重些第国13年出版的图书,作者是陈种船硕。

  • 作者 陈硕
  • 出版社 电子工业出版社
  • 出版时间 2013年1月15日
  • 页数 610 页
  • 定价 89 元

内容介来自

  本书主要讲述采判夜规考临执用现代C++ 在x86-64 Linux 上编写多线程TCP 网络服务程序的

  主流常规技术,重点讲解一种适应性较强的多线程服务器的编程模型,即one loop

  per thread。尼胜识你了渐这是在Linux 下以native 语言编写用户态高性能网络程序最成熟的模

  式,掌握之后可顺利地开发各类常见的服务端网络应用程序。本书以muduo 网络库

 老校度别显算处伤神静 为例,讲解这种编程模型的被减露意失卷本调镇使用方法及注意事项。

  本书的事是最审长密宗旨是贵精不贵多。掌握两种取治迅友正责路吗讨消银基本的同步原语就可以满足各种多线程同步

  的功能需求,还能写出更易用的同步设施。掌握一种进程间通信方式和一种多线程网

  络编程模型就足以应对日常开发任务,编写运行于公司内网环境的分布式服360百科务系统。

作者介绍

  陈木施状名员角硕,北京师范大学硕士,擅激农田预带弱微处十长C++ 多线程网络编程和实时分布式系统架构。

 绝般短领收接 曾在摩根士丹利IT 部门工作5 年,从事实时外汇交易系统开发。现在在美国加州硅

  谷某互联网大公司工作,从事大规模分布式系统的可靠性工程。编写了开源C++ 网

  络库muduo,参与翻译了《代码大全(第2 版)》和《C++ 编程规范(繁体版)》,整

  理了《C++ Primer (第4 版)(评注版)》,并曾多次在各地技术大会演讲。

作品目录

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

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

  1.1 当析构函数遇到温货货措速住愿多线程. . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

  1来自.1.1 线程安全的定义. . . . . . . . . . . . . . . . . . . . . 裂仍标钢觉. . . . . . . 4

  1.1.2 MutexLock 与MutexLockGuard . . . . . . . . . . . . . . . . . . . . 4

  1.1.3 一个线程安全的Counter 示例. . . . . . . . . . . . . . . . . . . . 4

  1.2 爱皮个喜对象的创建很简单. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

  1.3 销毁太难. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

  1.3.1 mutex 不是办法. . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

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

  1.4 线程安全的Ob360百科server 有多难. . . . . . . . . . . . . . . . . . . 顺测机云. . . . . . 8

  1.5 原始指针有何不妥. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

  1.6 神器shared_ptr/weak_ptr . . . . . 践况欢赵. . . . . . . . . . . . . . . . . . . . . 13

  1.7 插曲:系统地避免各种指针娘没晶斗错误. . . . . . . . . . . . . . . . . . . . . . 阳乎底生讲宁风. 14

  1.8 应用到Observer 上. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

  1.9 再流规广论shared_激练气太力景手我史ptr 的线程安全. . . . . 职最宣较. . . . . . . . . . . . . . . . . . . . 17

  1.10 shared_ptr 技术与陷阱. . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

  1.11 对象池. . 船队棉. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 皇雷取死神逐却混福律. . . . . 21

  1.11.1 enable_shared_from_this . . . . . . . . . . . . . . . . . . . . . . 23

  1.11.2 弱回调. . . . . . . 况背日展接半映值朝. . . . . . . . . . . . . . . . . . . . . . . . . . 24

  1.12 替代方案. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 元说汽六火静整护木. . . . 26

  1.13 心得与小结. . . . . 路与沙背. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

  1.14 Observer 之谬. 价石大盟练迅应艺统. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

  第2章 线程同步精要31

  2.1 互斥器(mutex) . . . . . . . . . . . . . . . . . . 真背较. . . . . . . . . . . . . 32

  2.1.1 只使用非递归的mutex . . . . . . . . . . . . . . . . . . . . . . . . 33

  2.1.2 死锁. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

  2.2 条件变量(condition variable) . . . . . . . . . . . . . . . . . . . . . . . 40

  2.3 不要用读写锁和信号量. . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

  2.4 封装MutexLock、MutexLockGuard、Condition . . . . . . . . . . . . . . 44

  2.5 线程安全的Singleton 实现. . . . . . . . . . . . . . . . . . . . . . . . . . 48

  2.6 sleep(3) 不是同步原语. . . . . . . . . . . . . . . . . . . . . . . . . . . . 50

  2.7 归纳与总结. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51

  2.8 借shared_ptr 实现copy-on-write . . . . . . . . . . . . . . . . . . . . . . 52

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

  3.1 进程与线程. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59

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

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

  3.3.1 one loop per thread . . . . . . . . . . . . . . . . . . . . . . . . . . 62

  3.3.2 线程池. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63

  3.3.3 推荐模式. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64

  3.4 进程间通信只用TCP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65

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

  3.5.1 必须用单线程的场合. . . . . . . . . . . . . . . . . . . . . . . . . 69

  3.5.2 单线程程序的优缺点. . . . . . . . . . . . . . . . . . . . . . . . . 70

  3.5.3 适用多线程程序的场景. . . . . . . . . . . . . . . . . . . . . . . . 71

  3.6 "多线程服务器的适用场合"例释与答疑. . . . . . . . . . . . . . . . . . 74

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

  4.1 基本线程原语的选用. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84

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

  4.3 Linux 上的线程标识. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89

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

  4.4.1 pthread_cancel 与C++ . . . . . . . . . . . . . . . . . . . . . . . 94

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

  4.5 善用__thread 关键字. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96

  4.6 多线程与IO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98

  4.7 用RAII 包装文件描述符. . . . . . . . . . . . . . . . . . . . . . . . . . . 99

  4.8 RAII 与fork() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101

  4.9 多线程与fork() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102

  4.10 多线程与signal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103

  4.11 Linux 新增系统调用的启示. . . . . . . . . . . . . . . . . . . . . . . . . . 105

  第5章 高效的多线程日志107

  5.1 功能需求. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109

  5.2 性能需求. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112

  5.3 多线程异步日志. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114

  5.4 其他方案. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120

  第2部分 muduo 网络库123

  第6章 muduo 网络库简介125

  6.1 由来. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125

  6.2 安装. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127

  6.3 目录结构. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129

  6.3.1 代码结构. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131

  6.3.2 例子. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134

  6.3.3 线程模型. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135

  6.4 使用教程. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136

  6.4.1 TCP 网络编程本质论. . . . . . . . . . . . . . . . . . . . . . . . . 136

  6.4.2 echo 服务的实现. . . . . . . . . . . . . . . . . . . . . . . . . . . 138

  6.4.3 七步实现finger 服务. . . . . . . . . . . . . . . . . . . . . . . . . 140

  6.5 性能评测. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144

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

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

  6.5.3 muduo 与Nginx 的吞吐量对比. . . . . . . . . . . . . . . . . . . 153

  6.5.4 muduo 与ZeroMQ 的延迟对比. . . . . . . . . . . . . . . . . . . 156

  6.6 详解muduo 多线程模型. . . . . . . . . . . . . . . . . . . . . . . . . . . 157

  6.6.1 数独求解服务器. . . . . . . . . . . . . . . . . . . . . . . . . . . . 157

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

  第7章 muduo 编程示例177

  7.1 五个简单TCP 示例. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178

  7.2 文件传输. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185

  7.3 Boost.Asio 的聊天服务器. . . . . . . . . . . . . . . . . . . . . . . . . . . 194

  7.3.1 TCP 分包. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194

  7.3.2 消息格式. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195

  7.3.3 编解码器LengthHeaderCodec . . . . . . . . . . . . . . . . . . . . 197

  7.3.4 服务端的实现. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198

  7.3.5 客户端的实现. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200

  7.4 muduo Buffer 类的设计与使用. . . . . . . . . . . . . . . . . . . . . . . 204

  7.4.1 muduo 的IO 模型. . . . . . . . . . . . . . . . . . . . . . . . . . 204

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

  7.4.3 Buffer 的功能需求. . . . . . . . . . . . . . . . . . . . . . . . . . 207

  7.4.4 Buffer 的数据结构. . . . . . . . . . . . . . . . . . . . . . . . . . 209

  7.4.5 Buffer 的操作. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211

  7.4.6 其他设计方案. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217

  7.4.7 性能是不是问题. . . . . . . . . . . . . . . . . . . . . . . . . . . . 218

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

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

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

  7.5.3 Protobuf 传输格式. . . . . . . . . . . . . . . . . . . . . . . . . . 226

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

  7.6.1 什么是编解码器(codec) . . . . . . . . . . . . . . . . . . . . . . 229

  7.6.2 实现ProtobufCodec . . . . . . . . . . . . . . . . . . . . . . . . . 232

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

  7.6.4 ProtobufCodec 与ProtobufDispatcher 的综合运用. . . . . . . 233

  7.6.5 ProtobufDispatcher 的两种实现. . . . . . . . . . . . . . . . . . 234

  7.6.6 ProtobufCodec 和ProtobufDispatcher 有何意义. . . . . . . . . 236

  7.7 限制服务器的最大并发连接数. . . . . . . . . . . . . . . . . . . . . . . . 237

  7.7.1 为什么要限制并发连接数. . . . . . . . . . . . . . . . . . . . . . 237

  7.7.2 在muduo 中限制并发连接数. . . . . . . . . . . . . . . . . . . . 238

  7.8 定时器. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240

  7.8.1 程序中的时间. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240

  7.8.2 Linux 时间函数. . . . . . . . . . . . . . . . . . . . . . . . . . . . 241

  7.8.3 muduo 的定时器接口. . . . . . . . . . . . . . . . . . . . . . . . . 242

  7.8.4 Boost.Asio Timer 示例. . . . . . . . . . . . . . . . . . . . . . . . 243

  7.8.5 Java Netty 示例. . . . . . . . . . . . . . . . . . . . . . . . . . . . 245

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

  7.10 用timing wheel 踢掉空闲连接. . . . . . . . . . . . . . . . . . . . . . . . 250

  7.10.1 timing wheel 原理. . . . . . . . . . . . . . . . . . . . . . . . . . 251

  7.10.2 代码实现与改进. . . . . . . . . . . . . . . . . . . . . . . . . . . . 254

  7.11 简单的消息广播服务. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257

  7.12 "串并转换"连接服务器及其自动化测试. . . . . . . . . . . . . . . . . . 260

  7.13 socks4a 代理服务器. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264

  7.13.1 TCP 中继器. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264

  7.13.2 socks4a 代理服务器. . . . . . . . . . . . . . . . . . . . . . . . . . 267

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

  7.14 短址服务. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 267

  7.15 与其他库集成. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268

  7.15.1 UDNS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270

  7.15.2 c-ares DNS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 272

  7.15.3 curl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273

  7.15.4 更多. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275

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

  8.0 什么都不做的EventLoop . . . . . . . . . . . . . . . . . . . . . . . . . . . 277

  8.1 Reactor 的关键结构. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280

  8.1.1 Channel class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280

  8.1.2 Poller class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283

  8.1.3 EventLoop 的改动. . . . . . . . . . . . . . . . . . . . . . . . . . . 287

  8.2 TimerQueue 定时器. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 290

  8.2.1 TimerQueue class . . . . . . . . . . . . . . . . . . . . . . . . . . . 290

  8.2.2 EventLoop 的改动. . . . . . . . . . . . . . . . . . . . . . . . . . . 292

  8.3 EventLoop::runInLoop() 函数. . . . . . . . . . . . . . . . . . . . . . . . 293

  8.3.1 提高TimerQueue 的线程安全性. . . . . . . . . . . . . . . . . . . 296

  8.3.2 EventLoopThread class . . . . . . . . . . . . . . . . . . . . . . . . 297

  8.4 实现TCP 网络库. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299

  8.5 TcpServer 接受新连接. . . . . . . . . . . . . . . . . . . . . . . . . . . . 303

  8.5.1 TcpServer class . . . . . . . . . . . . . . . . . . . . . . . . . . . . 304

  8.5.2 TcpConnection class . . . . . . . . . . . . . . . . . . . . . . . . . 305

  8.6 TcpConnection 断开连接. . . . . . . . . . . . . . . . . . . . . . . . . . . 308

  8.7 Buffer 读取数据. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 313

  8.7.1 TcpConnection 使用Buffer 作为输入缓冲. . . . . . . . . . . . . 314

  8.7.2 Buffer::readFd() . . . . . . . . . . . . . . . . . . . . . . . . . . 315

  8.8 TcpConnection 发送数据. . . . . . . . . . . . . . . . . . . . . . . . . . . 316

  8.9 完善TcpConnection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320

  8.9.1 SIGPIPE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321

  8.9.2 TCP No Delay 和TCP keepalive . . . . . . . . . . . . . . . . . . 321

  8.9.3 WriteCompleteCallback 和HighWaterMarkCallback . . . . . . . 322

  8.10 多线程TcpServer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 324

  8.11 Connector . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 327

  8.12 TcpClient . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332

  8.13 epoll . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333

  8.14 测试程序一览. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 336

  第3部分 工程实践经验谈337

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

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

  9.1.1 分布式系统的本质困难. . . . . . . . . . . . . . . . . . . . . . . . 343

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

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

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

  9.2.2 "能随时重启进程"作为程序设计目标. . . . . . . . . . . . . . . 354

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

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

  9.4.1 错误做法. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 361

  9.4.2 正确做法. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 362

  9.4.3 TCP 协议的启示. . . . . . . . . . . . . . . . . . . . . . . . . . . . 363

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

  9.6 为系统演化做准备. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 367

  9.6.1 可扩展的消息格式. . . . . . . . . . . . . . . . . . . . . . . . . . 368

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

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

  9.7.1 单元测试的能与不能. . . . . . . . . . . . . . . . . . . . . . . . . 370

  9.7.2 分布式系统测试的要点. . . . . . . . . . . . . . . . . . . . . . . . 373

  9.7.3 分布式系统的抽象观点. . . . . . . . . . . . . . . . . . . . . . . . 374

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

  9.7.5 其他用处. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 379

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

  9.8.1 境界1:全手工操作. . . . . . . . . . . . . . . . . . . . . . . . . 382

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

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

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

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

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

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

  10.1.2 C 语言的编译模型. . . . . . . . . . . . . . . . . . . . . . . . . . . 398

  10.2 C++ 的编译模型. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 399

  10.2.1 单遍编译. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 399

  10.2.2 前向声明. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 402

  10.3 C++ 链接(linking) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 404

  10.3.1 函数重载. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 406

  10.3.2 inline 函数. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 407

  10.3.3 模板. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 409

  10.3.4 虚函数. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 414

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

  10.4.1 头文件的害处. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 416

  10.4.2 头文件的使用规则. . . . . . . . . . . . . . . . . . . . . . . . . . 417

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

  10.5.1 动态库是有害的. . . . . . . . . . . . . . . . . . . . . . . . . . . . 423

  10.5.2 静态库也好不到哪儿去. . . . . . . . . . . . . . . . . . . . . . . . 424

  10.5.3 源码编译是王道. . . . . . . . . . . . . . . . . . . . . . . . . . . . 428

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

  11.1 朴实的C++ 设计. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 429

  11.2 程序库的二进制兼容性. . . . . . . . . . . . . . . . . . . . . . . . . . . . 431

  11.2.1 什么是二进制兼容性. . . . . . . . . . . . . . . . . . . . . . . . . 432

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

  11.2.3 哪些做法多半是安全的. . . . . . . . . . . . . . . . . . . . . . . . 435

  11.2.4 反面教材:COM . . . . . . . . . . . . . . . . . . . . . . . . . . . 435

  11.2.5 解决办法. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 436

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

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

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

  11.3.3 虚函数作为接口的弊端. . . . . . . . . . . . . . . . . . . . . . . . 439

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

  11.3.5 Java 是如何应对的. . . . . . . . . . . . . . . . . . . . . . . . . . 443

  11.4 动态库接口的推荐做法. . . . . . . . . . . . . . . . . . . . . . . . . . . . 443

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

  11.5.1 基本用途. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 450

  11.5.2 对程序库的影响. . . . . . . . . . . . . . . . . . . . . . . . . . . . 451

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

  11.6 iostream 的用途与局限. . . . . . . . . . . . . . . . . . . . . . . . . . . . 457

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

  11.6.2 iostream 的设计初衷. . . . . . . . . . . . . . . . . . . . . . . . . 461

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

  11.6.4 iostream 在使用方面的缺点. . . . . . . . . . . . . . . . . . . . . 464

  11.6.5 iostream 在设计方面的缺点. . . . . . . . . . . . . . . . . . . . . 468

  11.6.6 一个300 行的memory buffer output stream . . . . . . . . . . . 476

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

  11.7 值语义与数据抽象. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 482

  11.7.1 什么是值语义. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 482

  11.7.2 值语义与生命期. . . . . . . . . . . . . . . . . . . . . . . . . . . . 483

  11.7.3 值语义与标准库. . . . . . . . . . . . . . . . . . . . . . . . . . . . 488

  11.7.4 值语义与C++ 语言. . . . . . . . . . . . . . . . . . . . . . . . . . 488

  11.7.5 什么是数据抽象. . . . . . . . . . . . . . . . . . . . . . . . . . . . 490

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

  11.7.7 数据抽象的例子. . . . . . . . . . . . . . . . . . . . . . . . . . . . 495

  第12章 C++ 经验谈501

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

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

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

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

  12.2.1 内存管理的基本要求. . . . . . . . . . . . . . . . . . . . . . . . . 507

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

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

  12.2.4 现实的开发环境. . . . . . . . . . . . . . . . . . . . . . . . . . . . 509

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

  12.2.6 解决办法:替换malloc() . . . . . . . . . . . . . . . . . . . . . . 512

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

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

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

  12.3.1 语言标准怎么说. . . . . . . . . . . . . . . . . . . . . . . . . . . . 515

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

  12.3.3 其他语言的规定. . . . . . . . . . . . . . . . . . . . . . . . . . . . 516

  12.3.4 脚本语言解释器代码. . . . . . . . . . . . . . . . . . . . . . . . . 517

  12.3.5 硬件实现. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 521

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

  12.4.1 系统函数的依赖注入. . . . . . . . . . . . . . . . . . . . . . . . . 522

  12.4.2 链接期垫片(link seam) . . . . . . . . . . . . . . . . . . . . . . 524

  12.5 慎用匿名namespace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 526

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

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

  12.5.3 匿名namespace 的不利之处. . . . . . . . . . . . . . . . . . . . . 527

  12.5.4 替代办法. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 529

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

  12.6.1 对diff 友好的代码格式. . . . . . . . . . . . . . . . . . . . . . . . 530

  12.6.2 对grep 友好的代码风格. . . . . . . . . . . . . . . . . . . . . . . 537

  12.6.3 一切为了效率. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 538

  12.7 再探std::string . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 539

  12.7.1 直接拷贝(eager copy) . . . . . . . . . . . . . . . . . . . . . . . 540

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

  12.7.3 短字符串优化(SSO) . . . . . . . . . . . . . . . . . . . . . . . . 543

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

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

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

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

  12.8.4 用partition() 实现"重排数组,让奇数位于偶数前面" . . . . 553

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

  第4 部分附录559

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

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

  附录C 关于Boost 的看法591

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

  参考文献599

标签:

  • 关注微信
上一篇:龙泉驿酒楼

相关文章