网络编程I/O模型

任何一个网络程序,所做的事情可以总结成下面几种:
●read:从套接字读取数据
●decode:对收到的数据进行解析
●compute:根据解析之后的内容,进行计算和处理
●encode:将处理之后的结果,按照约定的格式进行编码
●send:通过套接字把结果发出去

fork

概念:
 使用fork创建子进程为每个到达的客户连接服务。

缺点:
 随着客户数的变多,fork 的子进程也越来越多,即使客户和服务器之间的交互比较少,这样的子进程也不能被销毁,一直需要存在。使用 fork 的方式处理非常简单,它的缺点是处理效率不高,fork 子进程的开销太大。
网络编程I/O模型

pthread

概念:
 使用了 pthread_create 创建子线程来代替进程

缺点:虽然相比于fork效率有一定的提高,但是每次创建一个线程的开销仍然是不小的。

改进:使用线程池,在每次新连接到达时,从线程池挑选线程为之服务,减少了线程创建的开销。但是还是没有解决空闲连接占用资源的问题。
网络编程I/O模型

single reactor thread

概念:
一个 reactor 线程上同时负责分发 acceptor 的事件、已连接套接字的 I/O 事件。
事件驱动模式:
 事件驱动模式是一种比较好的模式,因为这种模式是符合大规模生产的需求的。我们的生活中遍地都是类似的模式。

举例:
 比如你去咖啡店喝咖啡,你点了一杯咖啡在一旁喝着,服务员也不会管你,等你有续杯需求的时候,再去和服务员提(触发事件),服务员满足了你的需求,你就继续可以喝着咖啡玩手机。整个柜台的服务方式就是一个事件驱动的方式。

单线程的缺点
 单 reactor 线程既分发连接建立,又分发已建立连接的 I/O,有点忙不过来,在实战中的表现可能就是客户端连接成功率偏低。
网络编程I/O模型

single reactor thread + worker threads

概念:
 反应堆线程只负责处理 I/O 相关的工作,业务逻辑相关的工作都被裁剪成一个一个的小任务,放到线程池里由空闲的线程来执行。

原因:
 和 I/O 事件处理相比,应用程序的业务逻辑处理是比较耗时的,比如 XML 文件的解析、数据库记录的查找、文件资料的读取和传输、计算型工作的处理等,这些工作相对而言比较独立,它们会拖慢整个反应堆模式的执行效率。所以,将这些 decode、compute、enode 型工作放置到另外的线程池中,和反应堆线程解耦,是一个比较明智的选择。
网络编程I/O模型