IO多路復用之poll

2021-08-04 18:13:32 字數 3589 閱讀 6934

poll和select區別:

① poll伺服器監視的檔案描述符無上限;

② poll將輸入、輸出引數進行分離。

一、poll函式

函式格式如下所示:

#include 

int poll ( struct pollfd * fds, unsigned

int nfds, int timeout);

不同與select使用三個點陣圖來表示三個fdset的方式,poll使用乙個 pollfd的指標實現,即poll將輸入、輸出引數進行分離。

struct pollfd * fds

pollfd 結構體定義如下:

struct pollfd ;

每乙個pollfd結構體指定了乙個被監視的檔案描述符,可以傳遞多個結構體,指示poll()監視多個檔案描述符。

每個結構體的events域是監視該檔案描述符的事件掩碼,由使用者來設定這個域。

revents域是檔案描述符的操作結果事件掩碼,核心在呼叫返回時設定這個域。

events域中請求的任何事件都可能在revents域中返回。

合法的事件如下:

pollin        有資料可讀。

pollrdnorm      有普通資料可讀。

pollrdband     有優先資料可讀。

pollpri       有緊迫資料可讀。

pollout       寫資料不會導致阻塞。

pollwrnorm     寫普通資料不會導致阻塞。

pollwrband     寫優先資料不會導致阻塞。

pollmsgsigpoll   訊息可用

此外,revents域中還可能返回下列事件:

poller    指定的檔案描述符發生錯誤。

pollhup   指定的檔案描述符掛起事件。

pollnval  指定的檔案描述符非法。

這些事件在events域中無意義,因為它們在合適的時候總是會從revents中返回。

使用poll()和select()不一樣,你不需要顯式地請求異常情況報告。

pollin | pollpri等價於select()的讀事件.

pollout |pollwrband等價於select()的寫事件。

pollin等價於pollrdnorm |pollrdband

而pollout則等價於pollwrnorm。

例如,要同時監視乙個檔案描述符是否可讀和可寫,我們可以設定 events為pollin |pollout。在poll返回時,我們可以檢查revents中的標誌,對應於檔案描述符請求的events結構體。如果pollin事件被設定,則檔案描述符可以被讀取而不阻塞。如果pollout被設定,則檔案描述符可以寫入而不導致阻塞。這些標誌並不是互斥的:它們可能被同時設定,表示這個檔案描述符的讀取和寫入操作都會正常返回而不阻塞。

unsigned

int nfds,

nfds_t型別的引數,用於標記陣列fds中的結構體元素的總數量

int timeout

timeout引數指定等待的毫秒數,無論i/o是否準備好,poll都會返回。

timeout指定為負數值表示無限超時,使poll()一直掛起直到乙個指定事件發生

timeout為0指示poll呼叫立即返回並列出準備好i/o的檔案描述符,但並不等待其它的事件。這種情況下,poll()就像它的名字那樣,一旦選舉出來,立即返回。

poll( )返回值:成功時,poll()返回結構體中revents域不為0的檔案描述符個數。

如果在超時前沒有任何事件發生,poll()返回0。

失敗時,poll()返回-1,並設定errno為下列值之一:

ebadf         乙個或多個結構體中指定的檔案描述符無效。

efaultfds   指標指向的位址超出程序的位址空間。

eintr     請求的事件之前產生乙個訊號,呼叫可以重新發起。

einvalnfds  引數超出plimit_nofile值。

enomem   可用記憶體不足,無法完成請求。

二、**演示(伺服器唯讀演示)

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define size 100

static

void usage(const

char* proc)

int startup(char* ip, int port)

struct sockaddr_in local;

local.sin_family = af_inet;

local.sin_port = ntohs(port);

local.sin_addr.s_addr = inet_addr(ip);

if(bind(sock, (struct sockaddr*)&local, sizeof(local)) <0)

if(listen(sock, 10) <0)

return sock;

}int main(int argc, char* argv)

int listen_sock = startup(argv[1], atoi(argv[2]));

struct pollfd evs[size];

int i = 0;

for(; i1;

evs[i].events = -1;

evs[i].revents = -1;

}evs[0].fd = listen_sock;

evs[0].events = pollin;

int timeout = 3000;

while(1)

printf("get a client:%s %d\n", inet_ntoa(client.sin_addr),ntohs(client.sin_port));

int j = 1;

for(; jif(evs[j].fd == -1)

}if(j == size)

}else

if(i != 0 && evs[i].revents == pollin)

else

if(ss == 0)

else

}else

// write events}}

}}return

0;}

poll伺服器啟動:

I O多路復用之poll

poll的優點 1 poll 不要求開發者計算最大檔案描述符加一的大小。2 poll 在應付大數目的檔案描述符的時候速度更快,相比於select。3 它沒有最大連線數的限制,原因是它是基於鍊錶來儲存的。poll的缺點 1 大量的fd的陣列被整體複製於使用者態和核心位址空間之間,而不管這樣的複製是不是...

I O多路復用之poll

回憶一下 select介面 intselect int nfds,fd set readfds,fd set writefds,fd set exceptfds,struct timeval timeout select需要我們指定檔案描述符的最大值,然後取 0,nfds 這個範圍內的值檢視是在集合...

I O多路復用之poll

poll函式和select函式非常相似,但是函式介面不一樣。include int poll struct pollfd fdarray,unsigned long nfds,int timeout 返回 就緒描述字的個數,0 超時,1 出錯 第乙個引數是指向乙個結構陣列第乙個元素的指標。每個陣列元...