1、常见的几种磁盘调度算法?

读写一个磁盘块的时间的影响因素有:

  • 旋转时间(主轴转动盘面,使得磁头移动到适当的扇区上)
  • 寻道时间(制动手臂移动,使得磁头移动到适当的磁道上)
  • 实际的数据传输时间

其中,寻道时间最长,因此磁盘调度的主要目标是使磁盘的平均寻道时间最短。
1. 先来先服务
按照磁盘请求的顺序进行调度。
优点是公平和简单。缺点也很明显,因为未对寻道做任何优化,使平均寻道时间可能较长。
2. 最短寻道时间优先
优先调度与当前磁头所在磁道距离最近的磁道。
虽然平均寻道时间比较低,但是不够公平。如果新到达的磁道请求总是比一个在等待的磁道请求近,那
么在等待的磁道请求会一直等待下去,也就是出现饥饿现象。具体来说,两端的磁道请求更容易出现饥
饿现象。
3. 电梯扫描算法
电梯总是保持一个方向运行,直到该方向没有请求为止,然后改变运行方向。
电梯算法(扫描算法)和电梯的运行过程类似,总是按一个方向来进行磁盘调度,直到该方向上没有未
完成的磁盘请求,然后改变方向。
因为考虑了移动方向,因此所有的磁盘请求都会被满足,解决了 SSTF 的饥饿问题。

2、常⻅的IO模型,五种?异步IO应⽤场景?有什么缺点?

1) 同步
就是在发出⼀个功能调⽤时,在没有得到结果之前,该调⽤就不返回。*也就是必须⼀件⼀件事做*,等前⼀件做完了才能做下⼀件事。就是我调⽤⼀个功能,该功能没有结束前,我死等结果。
2) 异步
当⼀个异步过程调⽤发出后,调⽤者不能⽴刻得到结果。实际处理这个调⽤的部件在完成后,通过状态、通知和回调来通知调⽤者。就是我调⽤⼀个功能,不需要知道该功能结果,该功能有结果后通知我(回调通知)
3) 阻塞
阻塞调⽤是指调⽤结果返回之前,当前线程会被挂起(线程进⼊⾮可执⾏状态,在这个状态下,cpu不会给线程分配时间⽚,即线程暂停运⾏)。函数只有在得到结果之后才会返回。对于同步调⽤来说,很多时候当前线程还是激活的,只是从逻辑上当前函数没有返回⽽已。 就是调⽤我(函数),我(函数)没有接收完数据或者没有得到结果之前,我不会返回。
4) ⾮阻塞
指在不能⽴刻得到结果之前,该函数不会阻塞当前线程,⽽会⽴刻返回。就是调⽤我(函数),我(函数)⽴即返回,通过select通知调⽤者。
IO模型
1) 阻塞I/O
应⽤程序调⽤⼀个IO函数,导致应⽤程序阻塞,等待数据准备好。 如果数据没有准备好,⼀直等待….数据准备好了,从内核拷⻉到⽤户空间,IO函数返回成功指示。
2) ⾮阻塞I/O
我们把⼀个SOCKET接⼝设置为⾮阻塞就是告诉内核,当所请求的I/O操作⽆法完成时,不要将进程睡眠,⽽是返回⼀个错误。这样我们的I/O操作函数将不断的测试数据是否已经准备好,如果没有准备好,继续测试,直到数据准备好为⽌。在这个不断测试的过程中,会⼤ᰁ的占⽤CPU的时间。
3) I/O复⽤
I/O复⽤模型会⽤到select、poll、epoll函数,这⼏个函数也会使进程阻塞,但是和阻塞I/O所不同的的,这三个函数可以同时阻塞多个I/O操作。⽽且可以同时对多个读操作,多个写操作的I/O函数进⾏检测,直到有数据可读或可写时,才真正调⽤I/O操作函数。
4) 信号驱动I/O
⾸先我们允许套接⼝进⾏信号驱动I/O,并安装⼀个信号处理函数,进程继续运⾏并不阻塞。当数据准备好时,进程会收到⼀个SIGIO信号,可以在信号处理函数中调⽤I/O操作函数处理数据。
5) 异步I/O
当⼀个异步过程调⽤发出后,调⽤者不能⽴刻得到结果。实际处理这个调⽤的部件在完成后,通过状态、通知和回调来通知调⽤者的输⼊输出操作

3、IO复⽤的原理?零拷⻉?三个函数?epoll 的 LT 和 ET 模式的理解。

1) IO复⽤是Linux中的IO模型之⼀,IO复⽤就是进程预先告诉内核需要监视的IO条件,使得内核⼀旦发现进程指定的⼀个或多个IO条件就绪,就通过进程进程处理,从⽽不会在单个IO上阻塞了。Linux中,提供了select、poll、 epoll三种接⼝函数来实现IO复⽤。
2) Select
select的缺点:
① 单个进程能够监视的⽂件描述符的数ᰁ存在最⼤限制,通常是1024。由于select采⽤轮询的⽅式扫描⽂件描述符,⽂件描述符数量越多,性能越差;
② 内核/⽤户空间内存拷⻉问题,select需要⼤量句柄数据结构,产⽣巨⼤开销;
③ Select返回的是含有整个句柄的数组,应⽤程序需要遍历整个数组才能发现哪些句柄发⽣事件;
④ Select的触发⽅式是⽔平触发,应⽤程序如果没有完成对⼀个已经就绪的⽂件描述符进⾏IO操作,那么每次select调⽤还会将这些⽂件描述符通知进程。
3) Poll
与select相⽐,poll使⽤链表保存⽂件描述符,没有了监视⽂件数量的限制,但其他三个缺点依然存在
4) Epoll
上⾯所说的select缺点在epoll上不复存在,epoll使⽤⼀个⽂件描述符管理多个描述符,将⽤户关系的⽂件描述符的事件存放到内核的⼀个事件表中,这样在⽤户空间和内核空间的copy只需⼀次。Epoll是事件触发的,不是轮询查询的。没有最⼤的并发连接限制,内存拷⻉,利⽤mmap()⽂件映射内存加速与内核空间的消息传递。
区别总结:
1) ⽀持⼀个进程所能打开的最⼤连接数
① Select最⼤1024个连接,最⼤连接数有FD_SETSIZE宏定义,其⼤⼩是32位整数表示,可以改变宏定义进⾏修改,可以重新编译内核,性能可能会影响;
② Poll没有最⼤连接限制,原因是它是基于链表来存储的;
③ 连接数限数有上限,但是很⼤;
2) FD剧增后带来的IO效率问题
① 因为每次进⾏线性遍历,所以随着FD的增加会造成遍历速度下降,效率降低;
② Poll同上;
③ 因为epool内核中实现是根据每个fd上的callback函数来实现的,只有活跃的socket才会主动调⽤callback,所以在活跃socket较少的情况下,使⽤epoll没有前⾯两者的现象下降的性能问题。
3) 消息传递⽅式
① Select内核需要将消息传递到⽤户空间,都需要内核拷⻉;
② Poll同上;
③ Epoll通过内核和⽤户空间共享来实现的。
epoll 的 LT 和 ET 模式的理解:
epoll对⽂件描述符的操作有两种模式:LT(level trigger)和ET(edge trigger),LT是默认模式。
区别:
LT模式:当epoll_wait检测到描述符事件发⽣并将此事件通知应⽤程序,应⽤程序可以不⽴即处理该事件。下次调⽤epoll_wait时,会再次响应应⽤程序并通知此事件。
ET模式:当epoll_wait检测到描述符事件发⽣并将此事件通知应⽤程序,应⽤程序必须⽴即处理该事件。如果不处理,下次调⽤epoll_wait时,不会再次响应应⽤程序并通知此事件。
在 select/poll中,进程只有在调⽤⼀定⽅法后,内核才对所有监视的⽂件描述符进⾏扫描,⽽epoll事先通过epoll_ctl()来注册⼀个⽂件描述符,⼀旦某个⽂件描述符就绪时,内核会采⽤类似callback的回调机制,迅速激活这个⽂件描述符,当进程调⽤epoll_wait时便得到通知(此处去掉了遍历⽂件描述符,⽽是通过监听回调的机制,这也是epoll的魅⼒所在)。
Epoll 的优点主要体现咋如下⼏个⽅⾯:
1. 监视的描述符不受限制,它所⽀持的FD上限是最⼤可以打开⽂件的数⽬,这个数字⼀般远⼤于2048,举个例子,具体数⽬可以在cat/proc/sys/fs/file-max 查看,⼀般来说,这个数⽬和内存关系很⼤。
2. Select最⼤的缺点是进程打开的fd数⽬是有限制的,这对于连接数⽬较⼤的服务器来说根本不能满⾜,虽然也可以选择多进程的解决⽅案(Apache就是如此);不过虽然linux上⾯创建进程的代价较⼩,但仍旧不可忽视,加上进程间数据同步远⽐不上线程间同步⾼效,所以并不是⼀种完美的解决⽅案。
3. IO的效率不会随着监视fd的数量的增⻓⽽下降,epoll不同于select和poll的轮询⽅式,⽽是通过每个fd定义的回调函数来实现,只有就绪的fd才会执⾏回调函数。
4. 如果没有⼤量的idle -connection或者dead-connection,epoll的效率并不会⽐select/poll⾼很多,但是当遇到⼤量的idle- connection,就会发现epoll的效率⼤⼤⾼于select/poll。