阻塞IO
在内核将数据准备好之前, 系统调⽤会⼀直等待. 所有的套接字, 默认都是阻塞⽅式
⾮阻塞IO
如果内核还未将数据准备好, 系统调⽤仍然会直接返回, 并且返回EWOULDBLOCK错误码,⾮阻塞IO往往需要程序员循环的⽅式反复尝试读写⽂件描述符, 这个过程称为轮询. 这对CPU来说是较⼤的浪费, ⼀般只有特定场景下才使⽤
信号驱动IO
内核将数据准备好的时候, 使⽤SIGIO信号通知应⽤程序进⾏IO操作
IO多路转接
虽然从流程图上看起来和阻塞IO类似. 实际上最核⼼在于IO多路转接能够同时等待多个⽂件描述符的就绪状态
异步IO
由内核在数据拷⻉完成时, 通知应⽤程序(⽽信号驱动是告诉应⽤程序何时可以开始拷⻉数据)
其他⾼级IO
⾮阻塞IO,纪录锁,系统V流机制,I/O多路转接(也叫I/O多路复⽤),readv和writev函数以及存储映射IO(mmap),这些统称为⾼级IO
任何IO过程中,, 都包含两个步骤. 第⼀是等待, 第⼆是拷⻉. ⽽且在实际的应⽤场景中, 等待消耗的时间往往都远远⾼于拷⻉的时间. 让IO更⾼效, 最核⼼的办法就是让等待的时间尽量少.
同步通信 vs 异步通信
- 所谓同步,就是在发出⼀个调⽤时,在没有得到结果之前,该调⽤就不返回. 但是⼀旦调⽤返回,就得到返回值了; 换句话说,就是由调⽤者主动等待这个调⽤的结果;
- 异步则是相反,调⽤在发出之后,这个调⽤就直接返回了,所以没有返回结果; 换句话说,当⼀个异步过程调⽤发出后,调⽤者不会⽴刻得到结果; ⽽是在调⽤发出后,被调⽤者通过状态、通知来通知调⽤者,或通过回调函数处理这个调⽤
阻塞 vs ⾮阻塞
阻塞和⾮阻塞关注的是程序在等待调⽤结果(消息,返回值)时的状态
- 阻塞调⽤是指调⽤结果返回之前,当前线程会被挂起. 调⽤线程只有在得到结果之后才会返回.
- ⾮阻塞调⽤指在不能⽴刻得到结果之前,该调⽤不会阻塞当前线程.
⾮阻塞IO
#include <unistd.h>
#include <fcntl.h>
int fcntl(int fd,int cmd,...)
int fcntl(fd,F_GETFL);
int fcntl(fd,F_SETFL,flag | O_NONBLOOK);
重定向
#include <unistd.h>
int dup2(int oldfd,int newfd);
//new重定向old
//往new写相当于往old写