《Linux多线程服务器端编程》读书笔记第3章

时间:2022-07-17 23:05:21

《Linux多线程服务器端编程》第3章主要讲的是多线程服务器的适用场合与常用的编程模型。

1.进程和线程

一个进程是"内存中正在运行的程序“。每个进程都有自己独立的地址空间(address space)。将"进程"比喻为"人",每个人都有自己的记忆(memory),人与人通过谈话(消息传递)来交流,谈话既可以是面谈(同一台服务器),也可以在电话里谈(不同的服务器,有网络通信)。面谈和电话谈的区别在于,面谈可以立即知道对方是否死了(crash,SIGCHILD),而电话谈只能通过周期性的心跳来判断对方是否还活着。

线程的特点是共享进程地址空间,从而可以高效地共享数据。多线程的价值,可以更好地发挥多核处理器(multi-cores)的效能。

2.单线程服务器的常用模型

在高性能的网络程序中,使用最为广泛的恐怕要数 "non-blocking IO + IO multiplexing"这种模型,既Reactor模式。

程序的基本结构是一个事件循环(event loop),以事件驱动(event-driven)和事件回调的方式实现业务逻辑:

//代码仅为示意,没有完整考虑各种情况
while(!done){
int timeout_ms=max(,getNextTimedCallback());
int retval=::poll(fds,nfds,timeout_ms);
if(retval<){
处理错误,回调用户的error handler
}
else{
处理到期的timers,回调用户的timer handler
if(retval>){
处理IO事件,回调用户的IO event handler
}
}
}

Reactor模式的优点明显,不仅可以用于读写socket,连接的建立(connect/accept)甚至DNS解析都可以用非阻塞地方式进行,以提高并发度和吞吐量,对于IO密集的应用是个不错的选择。但基于事件驱动的编程模型也有其本质的缺点,它要求事件回调函数必须是非阻塞的。对于涉及网络IO的请求响应式协议,它容易割裂业务逻辑,使其散布于多个回调函数之中,相对不容易理解和维护。

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

1.每个请求创建一个线程,使用阻塞式IO操作。

2.使用线程池,同样使用阻塞式IO操作。与第一种相比,这是提高性能的措施.

3.使用non-blocking IO + IO multiplexing.

4. Leader/Follwer等高级模式。

4.推荐模式

总结起来,推荐的C++多线程服务器端编程模式为:one(event) loop per thread + thread pool

  • event loop(也叫IO loop)用作IO multiplexing,配合non-blocking IO和定时器.
  • thread pool用来做计算,具体可以是任务队列或生产者消费者队列。

服务器开发:跑在多核机器上的Linux用户态的没有用户界面的长期运行的网络应用程序,通常是分布式系统的组成部件。