【Linux程式設計】IO複用之poll詳解
poll系統呼叫
poll系統呼叫和select非常相似,關於select的詳解可以在本部落格中找到,poll也是在一定時間內輪詢監聽使用者感興趣的檔案描述符上的可讀、可寫和異常事件。
poll系統呼叫原型
#include<poll.h>
int poll(struct pollfd fdset[], nfds_t nfds, int timeout);
1)fdset引數是一個pollfd結構體型別的陣列,其定義如下:
struct pollfd{
int fd; /*檔案描述符,如果小於0。這個檔案描述符將會被程序忽略*/
short events; /*註冊的事件,即感興趣的事件。可以是一個事件,也可以是多個事件的按位或*/
short revents; /*實際發生的事件,由核心來賦值。需要與某種型別的事件按位與來確定某種事件是否發生*/
};
這個結構體指定了我們感興趣的檔案描述符上發生的可讀、可寫和異常事件。
與select不同,poll不是為每個事件構造一個描述符集合,而是用一個pollfd結構體陣列來指定使用者感興趣的檔案描述符及其事件。
poll事件型別如下表:
自Linux核心2.6.17開始,GUN為poll系統呼叫增加了一個POLLRDHUP事件,它在socket上接收到對方關閉連線的請求之後觸發,使用POLLRDHUP時,需要在程式碼最開始處定義 _GUN_SOURCE。
當然我們也可以通過read來判斷對方是否關閉了連線,當read返回0時,表示對方請求關閉連線。
2)nfds引數指定了pollfd結構體陣列fdset的大小,nfds_t是一個無符號長整型型別:
typedef unsigned long int nfds_t;
3)timeout引數指定poll的超時時間,單位是毫秒。
當timeout==-1時:永久等待,直到指定的描述符有事件發生或捕捉到訊號時返回。
當timeout==0時:不等待,測試完所有描述符後立即返回。
當timeout>0時:等待指定的毫秒,在超時時間內,當指定的描述符有事件發生或捕捉到訊號時返回。
poll返回值
poll的返回值含義與select相同。
1)返回-1,表示出錯,比如在等待期間捕捉到一個訊號。
2)返回0,表示在超時時間內沒有描述符準備好。
3)返回一個正值,表示已經準備好的描述符的數量。
poll函式的一個小例項
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <poll.h>
int main(){
struct pollfd fdset[1];
fdset[0].fd = 0;
fdset[0 ].events = POLLIN;
int ret;
char buf[100];
while(1){
ret = poll(fdset, 1, -1);
if(fdset[0].revents & POLLIN){
ret = read(0, buf, 100);
printf("讀取到%d個位元組的資料%s", ret, buf);
}
}
return 0;
}
這個小例項主要是監聽標準輸入上的POLLIN事件,當我們在鍵盤上敲入資料時,會觸發POLLIN事件,表示有資料可讀,然後poll返回。由核心修改的fdset[0].revents與POLLIN相與判斷是否發生了POLLIN事件,當為真則發生,就可以讀取鍵盤上的輸入資料了。