《Linux多线程服务端编程 使用muduo C++网络库》PDF下载

  • 购买积分:17 如何计算积分?
  • 作  者:陈硕著
  • 出 版 社:北京:电子工业出版社
  • 出版年份:2013
  • ISBN:9787121192821
  • 页数:600 页
图书介绍:本书主要讨论如何基于Linux平台编写C++程序——代码位于服务端,并且深处多线程、并发处理的现代开发场景。《Linux C++ 多线程服务端编程》描述了使用标准接口包括使用Linux独有的高级接口时,在功能和性能之间如何进行权衡取舍的策略。该书同样也是一本内行人士编写灵活、高效代码的学习指南。作为国内从事C++开发的黑客级人物,本书作者不仅阐释了系统接口应该如何工作,还介绍了它们实际上是如何工作的,以及怎样安全、有效地使用它们。可以说,本书包含了帮助你在任何层面编写更佳代码的实用技巧。

第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线程安全的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.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.4Buffer的数据结构 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 Pollerclass 283

8.1.3 EventLoop的改动 287

8.2TimerQueue定时器 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.5TcpServer接受新连接 303

8.5.1 TcpServer class 304

8.5.2 TcpConnection class 305

8.6TcpConnection断开连接 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分布式系统的软件不要求7x24可靠 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