登录 注册
当前位置:主页 > 资源下载 > 50 > 使用muduo C++网络库进行Linux多线程服务端编程

使用muduo C++网络库进行Linux多线程服务端编程

  • 更新:2024-09-24 10:02:08
  • 大小:140.94MB
  • 推荐:★★★★★
  • 来源:网友上传分享
  • 类别:C++ - 后端
  • 格式:ZIP

资源介绍

《Linux多线程服务端编程:使用muduo C++网络库》主要讲述采用现代C++在x86-64 Linux上编写多线程TCP网络服务程序的主流常规技术,重点讲解一种适应性较强的多线程服务器的编程模型,即one loop per thread。 目 录 第1部分C++ 多线程系统编程 第1章线程安全的对象生命期管理3 1.1当析构函数遇到多线程. . . . . . . . . . . . . . . . .. . . . . . . . . . . 3 1.1.1线程安全的定义. . . . . . . . . . . . . . . . .. . . . . . . . . . . 4 1.1.2MutexLock 与MutexLockGuard. . . . . . . . . . . . . . . . . . . . 4 1.1.3一个线程安全的Counter 示例.. . . . . . . . . . . . . . . . . . . 4 1.2对象的创建很简单. . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . 5 1.3销毁太难. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . 7 1.3.1mutex 不是办法. . . . . . . . . . . . . . . . . . . .. . . . . . . . 7 1.3.2作为数据成员的mutex 不能保护析构.. . . . . . . . . . . . . . 8 1.4线程安全的Observer 有多难.. . . . . . . . . . . . . . . . . . . . . . . . 8 1.5原始指针有何不妥. . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . 11 1.6神器shared_ptr/weak_ptr . . . . . . . . . .. . . . . . . . . . . . . . . . 13 1.7插曲:系统地避免各种指针错误. . . . . . . . . . . . . . . . .. . . . . . 14 1.8应用到Observer 上.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 1.9再论shared_ptr 的线程安全.. . . . . . . . . . . . . . . . . . . . . . . . 17 1.10shared_ptr 技术与陷阱. . . .. . . . . . . . . . . . . . . . . . . . . . . . 19 1.11对象池. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . . 21 1.11.1enable_shared_from_this . . . . . . . . . . . . . . . . . . . . . . 23 1.11.2弱回调. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . 24 1.12替代方案. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . 26 1.13心得与小结. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . 26 1.14Observer 之谬. . . .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 第2章线程同步精要 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.6sleep(3) 不是同步原语. . . .. . . . . . . . . . . . . . . . . . . . . . . . 50 2.7归纳与总结. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . 51 2.8借shared_ptr 实现copy-on-write. . . . . . . . . . . . . . . . . . . . . . 52 第3章多线程服务器的适用场合与常用编程模型 3.1进程与线程. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . 59 3.2单线程服务器的常用编程模型. . . . . . . . . . . . . . . . .. . . . . . . 61 3.3多线程服务器的常用编程模型. . . . . . . . . . . . . . . . .. . . . . . . 62 3.3.1one 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.2C/C++ 系统库的线程安全性. . . . . . . . . . . . . . . . .. . . . . . . . 85 4.3Linux 上的线程标识. . . . . . . . . . . . . . . . .. . . . . . . . . . . . . 89 4.4线程的创建与销毁的守则. . . . . . . . . . . . . . . . .. . . . . . . . . . 91 6pxhread_cancel 与C++ . .. . . . . . . . . . . . . . . . . . . . . 94 4.4.2exit(3) 在C++ 中不是线程安全的.. . . . . . . . . . . . . . . . 94 4.5善用__thread 关键字.. . . . . . . . . . . . . . . . . . . . . . . . . . . . 96 4.6多线程与IO . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . 98 4.7用RAII 包装文件描述符.. . . . . . . . . . . . . . . . . . . . . . . . . . 99 4.8RAII 与fork() . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . 101 4.9多线程与fork() . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . 102 4.10多线程与signal . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . 103 4.11Linux 新增系统调用的启示. . . . . . . . . . . . . . . . .. . . . . . . . . 105 第5章高效的多线程日志107 5.1功能需求. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . 109 5.2性能需求. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . 112 5.3多线程异步日志. . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . 114 5.4其他方案. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . 120 第2部分muduo 网络库 第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.1TCP 网络编程本质论. . . . . . . . . . . . . . . . .. . . . . . . . 136 6.4.2echo 服务的实现. . . . . . . . . . . . . . . . . . . .. . . . . . . 138 6.4.3七步实现finger 服务.. . . . . . . . . . . . . . . . . . . . . . . . 140 6.5性能评测. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . 144 6.5.1muduo 与Boost.Asio、libevent2的吞吐量对比. . . . . . . . . . 145 6.5.2击鼓传花:对比muduo 与libevent2的事件处理效率. . . . . . 148 6.5.3muduo 与Nginx 的吞吐量对比.. . . . . . . . . . . . . . . . . . 153 6.5.4muduo 与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.3Boost.Asio 的聊天服务器. . . .. . . . . . . . . . . . . . . . . . . . . . . 194 7.3.1TCP 分包. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . 194 7.3.2消息格式. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . 195 7.3.3编解码器LengthHeaderCodec . . . . . . . . . . .. . . . . . . . . 197 7.3.4服务端的实现. . . . . . . . . . . . . . . . .. . . . . . . . . . . . 198 7.3.5客户端的实现. . . . . . . . . . . . . . . . .. . . . . . . . . . . . 200 7.4muduo Buffer 类的设计与使用. . . .. . . . . . . . . . . . . . . . . . . 204 7.4.1muduo 的IO 模型.. . . . . . . . . . . . . . . . . . . . . . . . . 204 7.4.2为什么non-blocking 网络编程中应用层buffer是必需的. . . . 205 7.4.3Buffer 的功能需求. . . . . . . . . . . . . . . . . . . .. . . . . . 207 7.4.4Buffer 的数据结构. . . . . . . . . . . . . . . . . . . .. . . . . . 209 7.4.5Buffer 的操作. . . . . . . . . . . . . . . . . . . .. . . . . . . . . 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.3Protobuf 传输格式. . . .. . . . . . . . . . . . . . . . . . . . . . 226 7.6在muduo 中实现Protobuf编解码器与消息分发器. . . . . . . . . . . . 228 7.6.1什么是编解码器(codec). . . . . . . . . . . . . . . . . . . . . . 229 7.6.2实现ProtobufCodec . . . . . . . . . . . . .. . . . . . . . . . . . 232 7.6.3消息分发器(dispatcher)有什么用.. . . . . . . . . . . . . . . 232 7.6.4ProtobufCodec 与ProtobufDispatcher的综合运用. . . . . . . 233 7.6.5ProtobufDispatcher 的两种实现. . . .. . . . . . . . . . . . . . 234 7.6.6ProtobufCodec 和ProtobufDispatcher有何意义. . . . . . . . . 236 7.7限制服务器的最大并发连接数. . . . . . . . . . . . . . . . .. . . . . . . 237 7.7.1为什么要限制并发连接数. . . . . . . . . . . . . . . . .. . . . . 237 7.7.2在muduo 中限制并发连接数.. . . . . . . . . . . . . . . . . . . 238 7.8定时器. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . . 240 7.8.1程序中的时间. . . . . . . . . . . . . . . . .. . . . . . . . . . . . 240 7.8.2Linux 时间函数. . . . . . . . . . . . . . . . . . . .. . . . . . . . 241 7.8.3muduo 的定时器接口. . . . . . . . . . . . . . . . .. . . . . . . . 242 7.8.4Boost.Asio Timer 示例. . . .. . . . . . . . . . . . . . . . . . . . 243 7.8.5Java Netty 示例. . . .. . . . . . . . . . . . . . . . . . . . . . . . 245 7.9测量两台机器的网络延迟和时间差. . . . . . . . . . . . . . . . .. . . . 248 7.10用timing wheel 踢掉空闲连接.. . . . . . . . . . . . . . . . . . . . . . . 250 7.10.1timing wheel 原理. . . .. . . . . . . . . . . . . . . . . . . . . . 251 7.10.2代码实现与改进. . . . . . . . . . . . . . . . .. . . . . . . . . . . 254 7.11简单的消息广播服务. . . . . . . . . . . . . . . . .. . . . . . . . . . . . 257 7.12“串并转换”连接服务器及其自动化测试.. . . . . . . . . . . . . . . . . 260 7.13socks4a 代理服务器. . . .. . . . . . . . . . . . . . . . . . . . . . . . . . 264 7.13.1TCP 中继器. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . 264 7.13.2socks4a 代理服务器. . . .. . . . . . . . . . . . . . . . . . . . . . 267 7.13.3N : 1 与1 : N 连接转发.. . . . . . . . . . . . . . . . . . . . . . . 267 7.14短址服务. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . 267 7.15与其他库集成. . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . 268 7.15.1UDNS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270 7.15.2c-ares DNS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 272 7.15.3curl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273 7.15.4更多. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . 275 第8章muduo 网络库设计与实现277 8.0什么都不做的EventLoop . . . . . . . . . . . .. . . . . . . . . . . . . . . 277 8.1Reactor 的关键结构. . . .. . . . . . . . . . . . . . . . . . . . . . . . . . 280 8.1.1Channel class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280 8.1.2Poller class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283 8.1.3EventLoop 的改动. . . .. . . . . . . . . . . . . . . . . . . . . . . 287 8.2TimerQueue 定时器. . . .. . . . . . . . . . . . . . . . . . . . . . . . . . 290 8.2.1TimerQueue class . . . . . . . . . . . . . . . . . . . . . . . . . . . 290 8.2.2EventLoop 的改动. . . .. . . . . . . . . . . . . . . . . . . . . . . 292 8.3EventLoop::runInLoop() 函数.. . . . . . . . . . . . . . . . . . . . . . . 293 8.3.1提高TimerQueue 的线程安全性.. . . . . . . . . . . . . . . . . . 296 8.3.2EventLoopThread class . . . . . . . . . . . . . . . . . . . . . . . . 297 8.4实现TCP 网络库.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299 8.5TcpServer 接受新连接. . . .. . . . . . . . . . . . . . . . . . . . . . . . 303 8.5.1TcpServer class . . . . . . . . . . . . . . . . . . . . . . . . . . . . 304 8.5.2TcpConnection class . . . . . . . . . . . . . . . . . . . . . . . . . 305 8.6TcpConnection 断开连接. . . .. . . . . . . . . . . . . . . . . . . . . . . 308 8.7Buffer 读取数据. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . 313 8.7.1TcpConnection 使用Buffer 作为输入缓冲.. . . . . . . . . . . . 314 8.7.2Buffer::readFd() . . . . . . . . . . . . . . . . . . . . . . . . . . 315 8.8TcpConnection 发送数据. . . .. . . . . . . . . . . . . . . . . . . . . . . 316 8.9完善TcpConnection . . . . . . . . . . . . .. . . . . . . . . . . . . . . . . 320 8.9.1SIGPIPE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321 8.9.2TCP No Delay 和TCPkeepalive . . . . . . . . . . . . . . . . . . 321 8.9.3WriteCompleteCallback 和HighWaterMarkCallback. . . . . . . 322 8.10多线程TcpServer . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . 324 8.11Connector . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .327 8.12TcpClient . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .332 8.13epoll . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. 333 8.14测试程序一览. . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . 336 第3部分工程实践经验谈 第9章分布式系统工程实践339 9.1我们在技术浪潮中的位置. . . . . . . . . . . . . . . . .. . . . . . . . . . 341 9.1.1分布式系统的本质困难. . . . . . . . . . . . . . . . .. . . . . . . 343 9.1.2分布式系统是个险恶的问题. . . . . . . . . . . . . . . . .. . . . 344 9.2分布式系统的可靠性浅说. . . . . . . . . . . . . . . . .. . . . . . . . . . 349 9.2.1分布式系统的软件不要求7 [1] 24 可靠.. . . . . . . . . . . . . . . 352 9.2.2“能随时重启进程”作为程序设计目标.. . . . . . . . . . . . . . 354 9.3分布式系统中心跳协议的设计. . . . . . . . . . . . . . . . .. . . . . . . 356 9.4分布式系统中的进程标识. . . . . . . . . . . . . . . . .. . . . . . . . . . 360 9.4.1错误做法. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . 361 9.4.2正确做法. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . 362 9.4.3TCP 协议的启示. . . . . . . . . . . . . . . . . . . .. . . . . . . . 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:机群管理与namingservice 结合. . . .. . . . . . . . . 389 第10章C++ 编译链接模型精要391 10.1C 语言的编译模型及其成因. . . . . . . . . . . . . . . . .. . . . . . . . 394 10.1.1为什么C 语言需要预处理.. . . . . . . . . . . . . . . . . . . . . 395 10.1.2C 语言的编译模型. . . . . . . . . . . . . . . . .. . . . . . . . . . 398 10.2C++ 的编译模型. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . 399 10.2.1单遍编译. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . 399 10.2.2前向声明. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . 402 10.3C++ 链接(linking). . . . . . . . . . . . . . . . . . . . . . . . . . . . . 404 10.3.1函数重载. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . 406 10.3.2inline 函数. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . 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.1C++ 程序库的作者的生存环境. . . . . . . . . . . . . . . . .. . . 437 11.3.2虚函数作为库的接口的两大用途. . . . . . . . . . . . . . . . .. 438 11.3.3虚函数作为接口的弊端. . . . . . . . . . . . . . . . .. . . . . . . 439 11.3.4假如Linux 系统调用以COM接口方式实现. . . . . . . . . . . . 442 11.3.5Java 是如何应对的. . . . . . . . . . . . . . . . .. . . . . . . . . 443 11.4动态库接口的推荐做法. . . . . . . . . . . . . . . . .. . . . . . . . . . . 443 11.5以boost::function 和boost::bind取代虚函数. . . . . . . . . . . . . 447 11.5.1基本用途. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . 450 11.5.2对程序库的影响. . . . . . . . . . . . . . . . .. . . . . . . . . . . 451 11.5.3对面向对象程序设计的影响. . . . . . . . . . . . . . . . .. . . . 453 11.6iostream 的用途与局限. . . .. . . . . . . . . . . . . . . . . . . . . . . . 457 11.6.1stdio 格式化输入输出的缺点. . . . . . . . . . . . . . . . .. . . . 457 11.6.2iostream 的设计初衷. . . .. . . . . . . . . . . . . . . . . . . . . 461 11.6.3iostream 与标准库其他组件的交互. . . .. . . . . . . . . . . . . 463 11.6.4iostream 在使用方面的缺点. . . .. . . . . . . . . . . . . . . . . 464 11.6.5iostream 在设计方面的缺点. . . .. . . . . . . . . . . . . . . . . 468 11.6.6一个300 行的memorybuffer 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不要重载全局:perator new() . . . . . . . .. . . . . . . . . . . . . . 507 12.2.1内存管理的基本要求. . . . . . . . . . . . . . . . .. . . . . . . . 507 12.2.2重载:perator new() 的理由.. . . . . . . . . . . . . . . . . . 508 12.2.3:perator new() 的两种重载方式. . . .. . . . . . . . . . . . . 508 12.2.4现实的开发环境. . . . . . . . . . . . . . . . .. . . . . . . . . . . 509 12.2.5重载:perator new() 的困境.. . . . . . . . . . . . . . . . . . 510 12.2.6解决办法:替换malloc() . . . . . . . . . . . .. . . . . . . . . . 512 12.2.7为单独的class 重载:peratornew() 有问题吗. . . . . . . . . 513 12.2.8有必要自行定制内存分配器吗. . . . . . . . . . . . . . . . .. . . 513 12.3带符号整数的除法与余数. . . . . . . . . . . . . . . . .. . . . . . . . . . 514 12.3.1语言标准怎么说. . . . . . . . . . . . . . . . .. . . . . . . . . . . 515 12.3.2C/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.1C 语言的static 关键字的两种用法.. . . . . . . . . . . . . . . . 526 12.5.2C++ 语言的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部分附录 附录A谈一谈网络编程学习经验561 附录B从《C++ Primer(第4版)》入手学习C++ 579 附录C关于Boost 的看法591 附录D关于TCP 并发连接的几个思考题与试验593 参考文献599