阻塞的文件描述符稱為阻塞I/O,非阻塞的文件描述符稱為非阻塞I/O,這里的文件描述符能應(yīng)用于所有的文件描述符,不僅僅是socket。 針對阻塞I/O執(zhí)行的系統(tǒng)調(diào)用可能無法立刻完成而被操作系統(tǒng)掛起,知道等待的時間發(fā)生為止。socket的基礎(chǔ)API中可能被阻塞的系統(tǒng)調(diào)用包括accept,send,recv和connect。 針對非阻塞I/O執(zhí)行的系統(tǒng)調(diào)用則總是立刻返回,而不管時間是否發(fā)生。可以根據(jù)返回值來判斷執(zhí)行結(jié)果。 所以只有在時間已經(jīng)發(fā)生的情況下執(zhí)行非阻塞的I/O, 才能提高程序的效率。因此非阻塞I/O要和I/O通知機(jī)制一起使用,比如I/O復(fù)用和SIGIO信號。 I/O復(fù)用是最常使用的I/O通知機(jī)制。它指的是,應(yīng)用程序通過I/O復(fù)用函數(shù)向內(nèi)核注冊一組事件,內(nèi)核通過I/O復(fù)用函數(shù)將其中就緒的事件通知給應(yīng)用程序。linux中常用的I/O復(fù)用函數(shù)是select,poll, epoll_wait。 從理論上說,阻塞I/O,I/O復(fù)用以及信號驅(qū)動I/O都是同步I/O模型。因為在這三種I/O模型中,I/O的讀寫操作,都是在I/O時間發(fā)生后,由應(yīng)該程序完成的。而POSIX規(guī)范所定義的異步I/O模型則不同。對異步I/O而言,用戶可以直接對I/O執(zhí)行讀寫操作,這些操作告訴內(nèi)核用戶讀寫緩沖區(qū)的位置,以及I/O操作完成后內(nèi)核通知應(yīng)用程序的方式。異步I/O的讀寫操作總是立刻返回,而不論I/O是否阻塞的,因為真正的讀寫操作已經(jīng)由內(nèi)核接管。也就是說,同步I/O模型要求用戶代碼自行執(zhí)行I/O操作(將數(shù)據(jù)從內(nèi)核緩沖區(qū)讀取到用戶緩沖區(qū),或?qū)⒂脩艟彌_區(qū)的數(shù)據(jù)寫入內(nèi)核緩沖區(qū)),而異步I/O機(jī)制則由內(nèi)核來執(zhí)行I/O操作(數(shù)據(jù)在內(nèi)核緩沖區(qū)和用戶緩沖區(qū)之間的移動式有內(nèi)核在后來來完成)。 I/O模型對比
|
|