阻塞的文件描述符称为阻塞I/O,非阻塞的文件描述符称为非阻塞I/O,这里的文件描述符能应用于所有的文件描述符,不仅仅是socket。 针对阻塞I/O执行的系统调用可能无法立刻完成而被操作系统挂起,知道等待的时间发生为止。socket的基础API中可能被阻塞的系统调用包括accept,send,recv和connect。 针对非阻塞I/O执行的系统调用则总是立刻返回,而不管时间是否发生。可以根据返回值来判断执行结果。 所以只有在时间已经发生的情况下执行非阻塞的I/O, 才能提高程序的效率。因此非阻塞I/O要和I/O通知机制一起使用,比如I/O复用和SIGIO信号。 I/O复用是最常使用的I/O通知机制。它指的是,应用程序通过I/O复用函数向内核注册一组事件,内核通过I/O复用函数将其中就绪的事件通知给应用程序。linux中常用的I/O复用函数是select,poll, epoll_wait。 从理论上说,阻塞I/O,I/O复用以及信号驱动I/O都是同步I/O模型。因为在这三种I/O模型中,I/O的读写操作,都是在I/O时间发生后,由应该程序完成的。而POSIX规范所定义的异步I/O模型则不同。对异步I/O而言,用户可以直接对I/O执行读写操作,这些操作告诉内核用户读写缓冲区的位置,以及I/O操作完成后内核通知应用程序的方式。异步I/O的读写操作总是立刻返回,而不论I/O是否阻塞的,因为真正的读写操作已经由内核接管。也就是说,同步I/O模型要求用户代码自行执行I/O操作(将数据从内核缓冲区读取到用户缓冲区,或将用户缓冲区的数据写入内核缓冲区),而异步I/O机制则由内核来执行I/O操作(数据在内核缓冲区和用户缓冲区之间的移动式有内核在后来来完成)。 I/O模型对比
|
|
来自: 竹林深处371 > 《libevent》