裝了4天的操作系統 。。。呵呵收穫頗多。
緬懷Stevens大師。
最好的參考資料:
1.師從互聯網。
2.Linux man 命令:man 7 signal,man 7 socket。
3.UNP v1第25章 。
第一條:概述
信號驅動IO,不是異步IO。
信號驅動IO是指:進程預先告知內核,使得 當某個socketfd有events(事件)發生時,內核使用信號通知相關進程。
異步IO(Asynchronous IO)是指:進程執行IO系統調用(read / write)告知內核啓動某個IO操作,內核啓動IO操作後立即返回到進程。IO操作即內核當中的服務例程。Posix 通過 aio_XXX函數提供真正的異步IO(參見 man 7 aio).
linux 2.6.35中定義的相關信號:
#define SIGPOLL SIGIO /* Pollable event occurred (System V). */
#define SIGIO 29 /* I/O now possible (4.2 BSD). */
第二條: System 信號驅動IO。
System V Asynchronous I/O
APUE的描述:In System V, asynchronous I/O is part of the STREAMS system and works only with STREAMS devices and STREAMS pipes. The System V asynchronous I/O signal is SIGPOLL.To enable asynchronous I/O for a STREAMS device, we have to call ioctl with a second argument (request) of I_SETSIG.
在System V當中,異步IO是STREAMS機制的一部分,並且她只能工作在流設備和流管道上。System V 異步IO信號是SIGPOLL。我們可以用I_SETSIG爲第二個參數調用ioctl,來在一個設備上開啓異步IO功能。由於linux拋棄了 STREAMS機制,就不再討論了。呵呵。
第三條:BSD信號驅動IO。
BSD Asynchronous I/O
APUE的描述:Asynchronous I/O in BSD-derived systems is a combination of two signals: SIGIO and SIGURG. The former is the general asynchronous I/O signal, and the latter is used only to notify the process that out-of-band data has arrived on a network connection.
基於BSD系統的異步IO機制是通過SIGIO和SIGURG信號組合實現的。SIGIO用於一般的異步IO,SIGURG(urgent)僅用於提醒(notify)進程網絡連接上有帶外數據到達,什麼是帶外數據,就是一個字節的緊急數據,用於告訴對端,我們的機器上有某種緊急事件發生了,比方說要宕機。
(0)在描述符上開啓SIGIO信號驅動IO功能,只需3步,僅需3步喲,就可以不用輪詢機制來耗費CPU接收數據:
1調用signal或sigaction,爲信號SIGIO建立信號處理函數。
2設置套接口的屬主。通過調用fcntl得F_SETOWN命令,在套接口設置接收SIGIO信號的進程或進程組。
3開啓套接口上的信號驅動IO,通過fcntl的F_SETFL命令,在套接口上設置O_ASYNC。
(0.1)注:
1。ioctl的FIOASYNX功能也可實現第3步這個功能。
2。fctl和ioctl所引用的 描述符只能是終端和網絡socket。
例子:
signal(SIGIO, &input_handler);
fcntl(STDIN_FILENO, F_SETOWN, getpid());
oflags = fcntl(STDIN_FILENO, F_GETFL);
fcntl(STDIN_FILENO, F_SETFL, oflags | FASYNC);
(1)在描述符上開啓SIGURG信號驅動IO功能,只需2步。
1調用signal或sigaction,爲信號SIGURG建立信號處理函數。
2設置套接口的屬主。通過調用fcntl得F_SETOWN命令,在套接口設置接收SIGURG信號的進程或進程組。
(1.1)注:所引用的描述符只能是:支持帶外數據的網絡連接的socket描述符。
第四條:Linux信號驅動IO
Linux支持BSD的信號驅動IO。
(0)UDP套接口上SIGIO信號。
SIGIO在UDP使用是最合適的,UDP套接口上的SIGIO只在以下2種事件種產生:
1。套接口上有數據到達。
2。UDP套接口已經連接的前提下,套接口發生異步錯誤。
(1)TCP套接口上SIGIO信號。
SIGIO在TCP上幾乎無用原於產生這種信號的事件,實在是太多了。Stevens 指出:我們應該考慮只對“監聽(形容詞)TCPsocket”(描述符)使用SIGIO,因爲對於“監聽TCPsocket”產生SIGIO的唯一條件是新連接完成。