poll(函式)

poll(函式)

本詞條是多義詞,共2個義項
更多義項 ▼ 收起列表 ▲

poll是Linux中的字元設備驅動中的一個函式。Linux 2.5.44版本後,poll被epoll取代。和select實現的功能差不多,poll的作用是把當前的檔案指針掛到等待佇列。

基本介紹

  • 外文名:poll
  • 作用:把當前的檔案指針掛到等待佇列
  • 實現功能:和select功能差不多
  • 操作舉例:#include <stdio.h>
函式,poll實現功能,poll操作舉例,

函式

unsigned int (*poll)(struct file * fp, struct poll_table_struct * table)
此函式在系統調用select內部被使用,作用是把當前的檔案指針掛到設備內部定義的等待
佇列中。這裡的參數table可以不考慮,是在select函式實現過程中的一個內部變數。
函式具體實現時:
wait_queue_head_t t = ((struct mydev *)filp->private_data)->wait_queue;
poll_wait(filp, t, table);
return mask;
這裡mask可以是:
POLLIN | POLLRDNORM
POLLOUT | POLLWRNORM
等等。
poll()函式:這個函式是某些Unix系統提供的用於執行與select()函式同等功能的函式,下面是這個函式的聲明:
#include <poll.h>
int poll(struct pollfd fds[], nfds_t nfds, int timeout);
參數說明:
fds:是一個struct pollfd結構類型的數組,用於存放需要檢測其狀態的Socket描述符;每當調用這個函式之後,系統不會清空這個數組,操作起來比較方便;特別是對於socket連線比較多的情況下,在一定程度上可以提高處理的效率;這一點與select()函式不同,調用select()函式之後,select()函式會清空它所檢測的socket描述符集合,導致每次調用select()之前都必須把socket描述符重新加入到待檢測的集合中;因此,select()函式適合於只檢測一個socket描述符的情況,而poll()函式適合於大量socket描述符的情況;
nfds:nfds_t類型的參數,用於標記數組fds中的結構體元素的總數量;
timeout:是poll函式調用阻塞的時間,單位:毫秒;
返回值:
>0:數組fds中準備好讀、寫或出錯狀態的那些socket描述符的總數量;
==0:數組fds中沒有任何socket描述符準備好讀、寫,或出錯;此時poll逾時,逾時時間是timeout毫秒;換句話說,如果所檢測的socket描述符上沒有任何事件發生的話,那么poll()函式會阻塞timeout所指定的毫秒時間長度之後返回,如果timeout==0,那么poll() 函式立即返回而不阻塞,如果timeout==INFTIM,那么poll() 函式會一直阻塞下去,直到所檢測的socket描述符上的感興趣的事件發生是才返回,如果感興趣的事件永遠不發生,那么poll()就會永遠阻塞下去;
-1: poll函式調用失敗,同時會自動設定全局變數errno;

poll實現功能

poll和select實現功能差不多,但poll效率高,以後要多用poll
poll()接受一個指向結構'struct pollfd'列表的指針,其中包括了你想測試的檔案描述符和事件。事件由一個在結構中事件域的比特掩碼確定。當前的結構在調用後將被填寫並在事件發生後返回。在SVR4(可能更早的一些版本)中的 "poll.h"檔案中包含了用於確定事件的一些宏定義。事件的等待時間精確到毫秒 (但令人困惑的是等待時間的類型卻是int),當等待時間為0時,poll()函式立即返回,-1則使poll()一直掛起直到一個指定事件發生。下面是pollfd的結構。
struct pollfd {
int fd; /*檔案描述符*/
short events; /* 等待的需要測試事件 */
short revents; /* 實際發生了的事件,也就是返回結果 */
};
與select()十分相似,當返回正值時,代表滿足回響事件的檔案描述符的個數,如果返回0則代表在規定時間內沒有事件發生。如發現返回為負則應該立即查看 errno,因為這代表有錯誤發生。
如果沒有事件發生,revents會被清空,所以你不必多此一舉。
poll函式可用的測試值
常量
說明
POLLIN
普通或優先權帶數據可讀
POLLRDNORM
普通數據可讀
POLLRDBAND
優先權帶數據可讀
POLLPRI
高優先權數據可讀
POLLOUT
普通數據可寫
POLLWRNORM
普通數據可寫
POLLWRBAND
優先權帶數據可寫
POLLERR
發生錯誤
POLLHUP
發生掛起
POLLNVAL
描述字不是一個打開的檔案
例如fds[0].events = POLLIN; /*將測試條件設定成普通或優先權帶數據可讀*/
然後 int pollresult = poll(fds,xx,xx); //這樣就可以監聽fds裡面檔案描述符了,當滿足特定條件就返回,並將結果保存在revents中。

poll操作舉例

#include <stdio.h> 
#include <stdlib.h>#include <string.h>#include <time.h>#include <errno.h>#include <poll.h>#include <fcntl.h>#include <unistd.h>#define MAX_BUFFER_SIZE 1024#define IN_FILES 3#define TIME_DELAY 60*5#define MAX(a,b) ((a>b)?(a):(b))int main(int argc ,char **argv){  struct pollfd fds[IN_FILES];  char buf[MAX_BUFFER_SIZE];  int i,res,real_read, maxfd;  fds[0].fd = 0;  if((fds[1].fd=open("data1",O_RDONLY|O_NONBLOCK)) < 0)    {      fprintf(stderr,"open data1 error:%s",strerror(errno));      return 1;    }  if((fds[2].fd=open("data2",O_RDONLY|O_NONBLOCK)) < 0)    {      fprintf(stderr,"open data2 error:%s",strerror(errno));      return 1;    }  for (i = 0; i < IN_FILES; i++)    {      fds[i].events = POLLIN;    }  while(fds[0].events || fds[1].events || fds[2].events)    {      if (poll(fds, IN_FILES, TIME_DELAY) <= 0)    {     printf("Poll error\n");     return 1;    }      for (i = 0; i< IN_FILES; i++)    {     if (fds[i].revents)       {         memset(buf, 0, MAX_BUFFER_SIZE);         real_read = read(fds[i].fd, buf, MAX_BUFFER_SIZE);         if (real_read < 0)        {         if (errno != EAGAIN)           {             return 1;           }        }         else if (!real_read)        {         close(fds[i].fd);         fds[i].events = 0;        }         else        {         if (i == 0)           {             if ((buf[0] == 'q') || (buf[0] == 'Q'))            {             return 1;            }           }         else           {             buf[real_read] = '\0';             printf("%s", buf);           }        }       }    }    }  exit(0);}

相關詞條

熱門詞條

聯絡我們