poll函式實現多路復用

2021-08-14 19:44:19 字數 3450 閱讀 2781

struct pollfd

每乙個pollfd結構體指定了乙個被監視的檔案描述符,可以傳遞多個結構體,指示poll()監視多個檔案描述符。每個結構體的events域是監視該檔案描述符的事件掩碼,由使用者來設定這個域。revents域是檔案描述符的操作結果事件掩碼。核心在呼叫返回時設定這個域。events域中請求的任何事件都可能在revents域中返回。

pollin

有資料可讀。

pollrdnorm

有普通資料可讀。

pollrdband

有優先資料可讀。

pollpri

有緊迫資料可讀。

pollout

寫資料不會導致阻塞。

pollwrnorm

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

pollwrband

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

pollmsg

sigpoll 訊息可用。

此外,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被設定,則檔案描述符可以寫入而不導致阻塞。這些標誌並不是互斥的:它們可能被同時設定,表示這個檔案描述符的讀取和寫入操作都會正常返回而不阻塞。

timeout引數指定等待的毫秒數,無論i/o是否準備好,poll都會返回。timeout指定為負數值表示無限超時;timeout為0指示poll呼叫立即返回並列出準備好i/o的檔案描述符,但並不等待其它的事件。這種情況下,poll()就像它的名字那樣,一旦選舉出來,立即返回。

int poll(struct pollfd fdarray, nfds_t nfds, int timeout);

poll返回值和錯誤**

成功時,poll()返回結構體中revents域不為0的檔案描述符個數;如果在超時前沒有任何事件發生,poll()返回0;失敗時,poll()返回-1,並設定errno為下列值之一:

ebadf

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

efault

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

eintr

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

einval

nfds引數超出plimit_nofile值。

enomem

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

以上理論摘自 謝謝~~~

[cpp]view plain

copy

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#define myport 6666    // the port users will be connecting to

#define backlog 5     // how many pending connections queue will hold

#ifndef inftim

#define inftim -1

#endif

#define buf_size 1024

#define maxline 100

#define maxclient 5

intfd_access[backlog];    

// accepted connection fd

intconn_amount;    

// current connection amount

intmain(

void

)     

server_addr.sin_family = af_inet;         // host byte order

server_addr.sin_port = htons(myport);     // short, network byte order

server_addr.sin_addr.s_addr = inaddr_any; // automatically fill with my ip

memset(server_addr.sin_zero, '\0'

, sizeof

(server_addr.sin_zero));  

if(bind(sock_fd, (

struct

sockaddr *)&server_addr, 

sizeof

(server_addr)) == -1)   

if(listen(sock_fd, backlog) == -1)   

printf("listen port %d\n"

, myport);  

sin_size = sizeof

(client_addr);  

client[0].fd=sock_fd;  

client[0].events=pollin;  

for(i=1;i

client[i].fd=-1;  

while

(1)   

}  if( i == maxclient)  

if( i > maxsock )  

maxsock = i;  

if( --result<= 0 )  

continue

;  }  

for(i = 1; i <= maxsock; i++)  

else

perror("read error"

);  

}  else

if(len == 0)  

else

printf("%s\n"

,buf);  

if(--conn_no <= 0)  

break

;  }  

}  }  

exit(0);  

}  (end)   

以上是伺服器端

客戶端**見

poll實現I O多路復用

poll函式原型 引數說明 fds 是乙個struct pollfd結構型別的陣列,用於存放需要檢測其狀態的socket描述符 每當呼叫這個函式之後,系統不會清空這個陣列,操作起來比較方便 特別是對於socket連線比較多的情況下,在一定程度上可以提高處理的效率 這一點與select 函式不同,呼叫...

I O多路復用 poll

函式結構 int poll struct pollfd fds,nfds t nfds,int timeout 引數 返回值 和select一模一樣 events和revents events 關注事件 讀就緒 寫就緒 異常 輸入的時候起作用 revents 輸出結果,輸出的時候起作用 輸入輸出引數...

多路復用select與poll

華清遠見嵌入式學院 講師。在unix linux中有4中io模型,分別為 1 阻塞io 2 非阻塞io 3 io多路復用 4 訊號驅動io 這幾種io模型,阻塞io是最長用到的,並且操作相對簡單,但是缺點在於效率低下,尤其是在,同時操作多個io的時候,不能隨時的處理各個io操作。而非阻塞io可以解決...