1 用过哪些Linux命令?
2 写过shell脚本吗?shell脚本基本格式?
3 Linux I/O读写方式
Linux提供了3种磁盘与主存之间数据传输方式:
- 轮询
- 基于死循环对I/O端口不断检测
- I/O中断
- 当有数据到达时,磁盘主动向CPU发起I/O中断请求,由CPU负责数据的传输过程
- DMA传输
- 在I/O中断基础上引入了DMA(Direct Memory Access,直接存储器访问技术),由DMA负责数据的传输,减少I/O中断操作对CPU的资源消耗
4 Linux select&poll&epoll
-
select(1983年在BSD里实现)
- 时间复杂度O(n)
- 会修改传入的参数
- 轮询sock查找数据,数据量大开销很大
- 线程非安全
- 只能监视1024个连接
-
poll(1997年实现)
- 时间复杂度O(n)
- 线程非安全
-
epoll(2002年实现,Linux系统是epoll,FreeBSD和macosx用的是kqueue)
- 时间复杂度O(1)
- 不用轮询sock查找数据就能知道哪个sock有数据
- 线程安全
- select函数是阻塞的,可以注册自己感兴趣的IO请求,等到数据来时再处理,可以提高CPU利用率,epoll利用Reactor设计模式实现了这一机制。
- 只支持Linux系统
表面上看epoll的性能最好,但是在连接数少并且连接都十分活跃的情况下,select和poll的性能可能比epoll好,毕竟epoll的通知机制需要很多函数回调。
epoll数据结构(红黑树+双链表+回调机制)
第一步:epoll_create()系统调用。此调用返回一个句柄,之后所有的使用都依靠这个句柄来标识。
第二步:epoll_ctl()系统调用。通过此调用向epoll对象中添加、删除、修改感兴趣的事件,返回0标识成功,返回-1表示失败。
第三部:epoll_wait()系统调用。通过此调用收集收集在epoll监控中已经发生的事件。
5 Linux sendfile(零拷贝)
传统的IO传输方式(read/write)
read(file, tmp_buf, len);
write(socket, tmp_buf, len);
目标数据被复制了4次,涉及四次内核态和用户态的上下文切换:硬盘—>内核buf—>用户buf—>socket相关缓冲区—>协议引擎
senfile传输
sendfile(socket, file, len);
硬盘 >> kernel buffer (快速拷贝到kernel socket buffer) >> 协议栈