Reactor,Proactor,Actor

先来说说几种IO模型。

1. 实现层面的网络IO模型

分为:同步阻塞IO,同步非阻塞IO,IO多路复用,异步IO。

1.1 同步阻塞IO

就是linux系统的read和write函数,在调用的时候会被阻塞住,直到完成数据读取或写入。

1.2 同步非阻塞

和上面的API是一样的,只是在打开fd的时候会有一个O_NONBLOCKcanshu。这样当调用read和write的时候,如果没有准备好数据,会立即返回,不会阻塞,然后让应用程序不断去轮询。

1.3 IO多路复用

select、poll、epoll,主要用的是epoll。

1.3.1 select

select本质上是通过设置或检查存放fd标志位的数据结构进行下一步处理。 这带来缺点:

  1. 单个进程可监视的fd数量被限制,即能监听端口的数量有限 单个进程所能打开的最大连接数有FD_SETSIZE宏定义,其大小是32个整数的大小(在32位的机器上,大小就是3232,同理64位机器上FD_SETSIZE为3264),当然我们可以对进行修改,然后重新编译内核,但是性能可能会受到影响,这需要进一步的测试 一般该数和系统内存关系很大,具体数目可以cat /proc/sys/fs/file-max察看。32位机默认1024个,64位默认2048。
  2. 对socket是线性扫描,即轮询,效率较低: 仅知道有I/O事件发生,却不知是哪几个流,只会无差异轮询所有流,找出能读数据或写数据的流进行操作。同时处理的流越多,无差别轮询时间越长 - O(n)。
    当socket较多时,每次select都要通过遍历FD_SETSIZE个socket,不管是否活跃,这会浪费很多CPU时间。如果能给 socket 注册某个回调函数,当他们活跃时,自动完成相关操作,即可避免轮询,这就是epoll与kqueue。

1.3.2 poll

select类似,只是描述fd集合的方式不同,poll使用pollfd结构而非select的fd_set结构。 管理多个描述符也是进行轮询,根据描述符的状态进行处理,但poll没有最大文件描述符数量的限制。

poll和select同样存在一个缺点就是,包含大量文件描述符的数组被整体复制于用户态和内核的地址空间之间,而不论这些文件描述符是否就绪,它的开销随着文件描述符数量的增加而线性增大。

它将用户传入的数组拷贝到内核空间
然后查询每个fd对应的设备状态:
如果设备就绪 在设备等待队列中加入一项继续遍历
若遍历完所有fd后,都没发现就绪的设备 挂起当前进程,直到设备就绪或主动超时,被唤醒后它又再次遍历fd。这个过程经历多次无意义的遍历。

没有最大连接数限制,因其基于链表存储,其缺点:

  1. 大量fd数组被整体复制于用户态和内核地址空间间,而不管是否有意义
  2. 如果报告
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值