io多路复用的原理和实现_【网络】多线程和IO多路复用服务器的实现与比较

7252a8b5103fc7aabe3e954da51dca65.png

1 场景

对于通信模型来说,有服务器-客户端,也有点对点或者广播等方式。

对于网络来说,常用的模型是服务器-客户端,客户端主动发起请求,服务端接收请求并给予响应(request-response)。

根据请求/响应的应用场景不一样,服务器有不一样的名称。

获取Web页面的,称之为web服务器,使用的是http协议;

获取文件的,称之为FTP服务器,使用ftp协议;

或许自定义应用协议,定制一个专用服务器。不论是何种应用层协议的服务器,其共性在于传输层一般采用TCP协议, 而且服务器服务的客户端一般是多个。涉及到多个客户端时,就会有服务器并发的需求。

同时,不同的应用场景,对并发数的要求有所差异。

2 阻塞与非阻塞I/O

UNIX系统中一切且为文件,每个文件用文件描述符(fd)来标识,可以对文件进行open/close/read/write等操作。但是这里存在一个问题,比如说调用read函数读取文件中的数据时,这个文件有可能为空(没有数据),则有两种处理方式:

1)此时调用read函数的线程被挂起,直到文件非空,唤醒线程,则读取数据后正常返回。

2)立即返回,并标识错误状态。

前者线程被挂起,函数没有返回,相当于阻塞状态,这样的I/O称之为阻塞式I/O。

后者函数立即返回,相当于非阻塞状态,这样的I/O称之为非阻塞式I/O。

阻塞式I/O的编程逻辑较非阻塞式的简单,不用考虑程序执行的状态。

当一个线程被阻塞了,显然不能响应其他操作,那么就需要再启动另一个线程来响应其他操作,所以有多线程编程的需求。

3 多线程

使用多线程来处理多个客户端的请求,有两种方式,一种是有请求就建立一个线程,另一种是事先建立一定数量的线程(线程池)。

前者在建立,销毁线程时需要消耗内存资源以及占用CPU时间。两者都 会带来线程切换的性能开销,同时会带来线程安全的问题,然后就要加锁,加锁又会降低性能和增加编程复杂度。

多线程中可以使用阻塞I/O进行编程,阻塞时即挂起线程,不占用CPU资源。

当客户端的数量只有数十个时,可以采用多线程的方式进行处理。

部分代码:

/*

4 I/O多路复用

若不想使用多线程带来线程的切换开销和建立线程的内存花销,可以使用单线程的方式,那么此时显然就不能有阻塞式的I/O,否则就不能响应多个请求了。对于Socket编程而言,可以将accept/recv/send函数设置为非阻塞模式。对多个I/O进行并发处理,采用的是I/O复用技术,linux系统提供的接口有select/poll/epoll。

对于select/poll而言,分别将多个客户端socket fd放在数组中,然后进行轮询,检查是否有数据更新或者新的连接。因为是依次遍历轮询,且涉及用户态和内核态的切换,比较消耗时间,特别是当客户端数量较大时,依次轮询的时间复杂度为O(n)。但是没有多线程带来的缺点。

部分代码:

while 

5 总结

对于少量的客户端来说,多线程和poll这两种服务器模型的CPU占用率差异并不大。但是多线程的内存消耗会更大。

对于大量的客户端来说,需要考虑使用epoll的机制,将轮询的O(n)复杂度降低至O(1)。

同时需要根据CPU的核心数,以及CPU的个数来进行多进程(线程),充分榨干硬件资源。不行就需要增加服务器的数量(集群),分布式处理。

6 完整源码

多次测试,稳定运行,可以支持1000以内的并发。源码详见 github地址 :

https://github.com/Boooooots/server-client-model​github.com

测试中若有问题,可以交流~~~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
IO多路复用就是一种事件驱动的机制,它是指在单个线程中通过监听多个流的状态来同时接收和发送多个请求,同时提高资源利用效率,减少不必要的阻塞和等待时间。其主要的实现方式有以下几种: 1、select模型(轮询) select模型是一种最基本的IO多路复用技术,它通过轮询来监听IO事件,并阻塞在select()调用上,等待任何一个流的状态改变,然后根据事件类型进行相应的读写操作。 2、poll模型(链表) poll模型和select模型类似,也是通过轮询来监听IO事件,但是其在实现时使用链表来管理IO流,可以有效提高效率,同时也可以处理更多的并发请求。 3、epoll模型(红黑树) epoll模型可以说是目前最为流行的IO多路复用技术,它通过使用红黑树来管理IO流,监听事件只需要在需要监听的文件描述符上设置回调函数,每当有IO事件发生时就调用回调函数,处理读写请求时将相关的数据结构从内核空间复制到用户空间,这样就大大提高了效率。 4、kqueue模型(八叉树) kqueue模型是在BSD UNIX系统中首先实现的一种IO多路复用技术,其采用八叉树的数据结构来管理IO事件,可以高效处理大量并发请求,同时又不增加过多的系统负担。 总之,无论采用哪种IO多路复用技术,都可以有效提高系统的处理效率和资源利用率,降低了系统的负担,从而使得面对大量并发请求时,系统可以更加稳定和高效地进行处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值