基本信息
编辑推荐
示范在多核时代采用现代C++ 编写
多线程TCP 网络服务器的正规做法
内容简介
计算机书籍
《Linux多线程服务端编程:使用muduo C++网络库》主要讲述采用现代C++在x86-64 Linux上编写多线程TCP网络服务程序的主流常规技术,重点讲解一种适应性较强的多线程服务器的编程模型,即one loop per thread。这是在Linux下以native语言编写用户态高性能网络程序最成熟的模式,掌握之后可顺利地开发各类常见的服务端网络应用程序。本书以muduo网络库为例,讲解这种编程模型的使用方法及注意事项。
《Linux多线程服务端编程:使用muduo 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
前言
muduo 是一个基于非阻塞IO 和事件驱动的现代C++ 网络库,原生支持one loop per thread 这种IO 模型。muduo 适合开发Linux 下的面向业务的多线程服务端网络应用程序,其中“面向业务的网络编程”的定义见附录A。“现代C++”指的不是C++11 新标准,而是2005 年TR1 发布之后的C++ 语言和库。与传统C++ 相比,现代C++ 的变化主要有两方面:资源管理(见第1 章)与事件回调(见第449 页)。
本书不是多线程编程教程,也不是网络编程教程,更不是C++ 教程。读者应该已经大致读过《UNIX 环境高级编程》、《UNIX 网络编程》、《C++ Primer》或与之内容相近的书籍。本书不谈C++11,因为目前(2012 年)主流的Linux 服务端发行版的g++ 版本都还停留在4.4,C++11 进入实用尚需一段时日。
本书适用的硬件环境是主流x86-64 服务器,多路多核CPU、几十GB 内存、千兆以太网互联。除了第5 章讲诊断日志之外,本书不涉及文件IO。
本书分为四大部分,第1 部分“C++ 多线程系统编程”考察多线程下的对象生命期管理、线程同步方法、多线程与C++ 的结合、高效的多线程日志等。第2 部分“muduo 网络库”介绍使用现成的非阻塞网络库编写网络应用程序的方法,以及muduo 的设计与实现。第3 部分“工程实践经验谈”介绍分布式系统的工程化开发方法和C++ 在工程实践中的功能特性取舍。第4 部分“附录”分享网络编程和C++语言的学习经验。
本书的宗旨是贵精不贵多。掌握两种基本的同步原语就可以满足各种多线程同步的功能需求,还能写出更易用的同步设施。掌握一种进程间通信方式和一种多线程网络编程模型就足以应对日常开发任务,编写运行于公司内网环境的分布式服务系统。(本书不涉及分布式存储系统,也不涉及UDP。)
术语与排版范例
本书大量使用英文术语,甚至有少量英文引文。设计模式的名字一律用英文,例如Observer、Reactor、Singleton。在中文术语不够突出时,也会使用英文,例如class、heap、event loop、STL algorithm 等。注意几个中文C++ 术语: 对象实体(instance)、函数重载决议(resolution)、模板具现化(instantiation)、覆写(override)虚函数、提领(dereference)指针。本书中的英语可数名词一般不用复数形式,例如两个class,6 个syscall;但有时会用(s) 强调中文名词是复数。fd 是文件描述符(file descriptor)的缩写。“CPU 数目”一般指的是核(core)的数目。容量单位kB、MB、GB 表示的字节数分别为103、106、109,在特别强调准确数值时,会分别用KiB、MiB、GiB 表示210、220、230 字节。用诸如§11.5 表示本书第11.5 节,L42 表示上下文中出现的第42 行代码。[JCP]、[CC2e] 等是参考文献,见书末清单。
一般术语用普通罗马字体,如mutex、socket;C++ 关键字用无衬线字体,如class、this、mutable;函数名和class 名用等宽字体,如fork(2)、muduo::EventLoop,其中fork(2) 表示系统函数fork() 的文档位于manpage 第2 节,可以通过man 2 fork命令查看。如果函数名或类名过长,可能会折行,行末有连字号“-”,如EventLoop-ThreadPool。文件路径和URL 采用窄字体,例如muduo/base/Date.h、http://chenshuo.com。用中文楷体表示引述别人的话。
代码
本书的示例代码以开源项目的形式发布在GitHub 上,地址是http://github.com/chenshuo/recipes/ 和http://github.com/chenshuo/muduo/。本书配套页面提供全部源代码打包下载,正文中出现的类似recipes/thread 的路径是压缩包内的相对路径,读者不难找到其对应的GitHub URL。本书引用代码的形式如下,左侧数字是文件的行号,右侧的“muduo/base/Types.h”是文件路径1。例如下面这几行代码是muduo::string 的typedef。
muduo/base/Types.h
15 namespace muduo
16 {
17
18 #ifdef MUDUO_STD_STRING
19 using std::string;
20 #else // !MUDUO_STD_STRING
21 typedef __gnu_cxx::__sso_string string;
22 #endif
媒体评论
谈一谈网络编程学习经验
本文谈一谈我在学习网络编程方面的一些个人经验。“网络编程”这个术语的范围很广,本文指用Sockets API 开发基于TCP/IP 的网络应用程序,具体定义见§A.1.5 “网络编程的各种任务角色”。
受限于本人的经历和经验,本附录的适应范围是:
x86-64 Linux 服务端网络编程,直接或间接使用Sockets API。
公司内网。不一定是局域网,但总体位于公司防火墙之内,环境可控。
本文可能不适合:
PC 客户端网络编程,程序运行在客户的PC 上,环境多变且不可控。
Windows 网络编程。
面向公网的服务程序。
高性能网络服务器。
本文分两个部分:
1. 网络编程的一些“胡思乱想”,以自问自答的形式谈谈我对这一领域的认识。
2. 几本必看的书,基本上还是W. Richard Stevents 的那几本。
另外,本文没有特别说明时均暗指TCP 协议,“连接”是“TCP 连接”,“服务
端”是“TCP 服务端”。
A.1 网络编程的一些“胡思乱想”
以下大致列出我对网络编程的一些想法,前后无关联。
A.1.1 网络编程是什么
网络编程是什么?是熟练使用Sockets API 吗?说实话,在实际项目里我只用过
书摘
谈一谈网络编程学习经验
本文谈一谈我在学习网络编程方面的一些个人经验。“网络编程”这个术语的范围很广,本文指用Sockets API 开发基于TCP/IP 的网络应用程序,具体定义见§A.1.5 “网络编程的各种任务角色”。
受限于本人的经历和经验,本附录的适应范围是:
x86-64 Linux 服务端网络编程,直接或间接使用Sockets API。
公司内网。不一定是局域网,但总体位于公司防火墙之内,环境可控。
本文可能不适合:
PC 客户端网络编程,程序运行在客户的PC 上,环境多变且不可控。
Windows 网络编程。
面向公网的服务程序。
高性能网络服务器。
本文分两个部分:
1. 网络编程的一些“胡思乱想”,以自问自答的形式谈谈我对这一领域的认识。
2. 几本必看的书,基本上还是W. Richard Stevents 的那几本。
另外,本文没有特别说明时均暗指TCP 协议,“连接”是“TCP 连接”,“服务
端”是“TCP 服务端”。
A.1 网络编程的一些“胡思乱想”
以下大致列出我对网络编程的一些想法,前后无关联。
A.1.1 网络编程是什么
网络编程是什么?是熟练使用Sockets API 吗?说实话,在实际项目里我只用过