Linux Socket poll
#include <poll.h>
int poll(struct pollfd fd[], nfds_t nfds, int timeout);
參數:
1)第一個參數:一個結構數組,struct pollfd結構如下:
struct pollfd{
int fd;????????????? //文件描述符
short events;??? //請求的事件
short revents;?? //返回的事件
};
events和revents是通過對代表各種事件的標志進行邏輯或運算構建而成的。events包括要監視的事件,poll用已經發生的事件填充revents。poll函數通過在revents中設置標志肌膚POLLHUP、POLLERR和POLLNVAL來反映相關條件的存在。不需要在events中對于這些標志符相關的比特位進行設置。如果fd小于0, 則events字段被忽略,而revents被置為0.標準中沒有說明如何處理文件結束。文件結束可以通過revents的標識符POLLHUN或返回0字節的常規讀操作來傳達。即使POLLIN或POLLRDNORM指出還有數據要讀,POLLHUP也可能會被設置。因此,應該在錯誤檢驗之前處理正常的讀操作。
poll函數的事件標志符值
| 常量 | 說明 |
| POLLIN | 普通或優先級帶數據可讀 |
| POLLRDNORM | 普通數據可讀 |
| POLLRDBAND | 優先級帶數據可讀 |
| POLLPRI | 高優先級數據可讀 |
| POLLOUT | 普通數據可寫 |
| POLLWRNORM | 普通數據可寫 |
| POLLWRBAND | 優先級帶數據可寫 |
| POLLERR | 發生錯誤 |
| POLLHUP | 發生掛起 |
| POLLNVAL | 描述字不是一個打開的文件 |
?
注意:后三個只能作為描述字的返回結果存儲在revents中,而不能作為測試條件用于events中。
2)第二個參數nfds:要監視的描述符的數目。
3)最后一個參數timeout:是一個用毫秒表示的時間,是指定poll在返回前沒有接收事件時應該等待的時間。如果? 它的值為-1,poll就永遠都不會超時。如果整數值為32個比特,那么最大的超時周期大約是30分鐘。
?
| timeout值 | 說明 |
| INFTIM | 永遠等待 |
| 0 | 立即返回,不阻塞進程 |
| >0 | 等待指定數目的毫秒數 |
例子程序:
在/root/pro/fd1 /root/pro/fd2中分別有內容,
1234
5678
和
1122
3344
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <stropts.h>
#include <sys/poll.h>
#include <sys/stropts.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <poll.h>
#define BUFSIZE 1024
int main(int argc, char *argv[])
{
?? ?char buf[BUFSIZE];
?? ?int bytes;
?? ?struct pollfd *pollfd;
?? ?int i=0;
?? ?int nummonitor=0;
?? ?int numready;
?? ?int errno;
?? ?char *str;
?? ?if(argc != 3)
?? ?{
?? ??? ?fprintf(stderr,"Usage:the argc num error\n");
?? ??? ?exit(1);
?? ?}
?? ?if((pollfd = (struct pollfd*)calloc(2, sizeof(struct pollfd))) == NULL) //為struct pollfd分配空間
?? ??????? exit(1);
??? ??? ?for(i; i<2; i++) //初始化化struct pollfd結構
?? ?{
?? ??? ?str = (char*)malloc(14*sizeof(char));?? ??? ?
?? ??? ?memcpy(str,"/root/pro/",14);
?? ??? ?strcat(str,argv[i+1]);//注意,需要把路勁信息放到str中,否則opne("/root/pro/argv[i]",O_RDONLY)會出錯
?? ??? ?printf("str=%s\n",str);//原因在于,在” “之中的argv[i]是字符串,不會用變量代替argv[i].
?? ??? ?(pollfd+i)->fd = open(str,O_RDONLY);
?? ??? ?if((pollfd+i)->fd >= 0)
?? ??? ?fprintf(stderr, "open (pollfd+%d)->fd:%s\n", i, argv[i+1]);
?? ??? ?nummonitor++;
?? ??? ?(pollfd+i)->events = POLLIN;
?? ?}
?? ?printf("nummonitor=%d\n",nummonitor);
? ?? ?
?? ?while(nummonitor > 0)
?? ?{
?? ??? ?numready = poll(pollfd, 2, -1);
?? ??? ?if ((numready == -1) && (errno == EINTR))
?? ??? ??? ?continue;??????? //被信號中斷,繼續等待
?? ??? ?else if (numready == -1)
?? ??? ??? ?break; //poll真正錯誤,推出
?? ??? ?printf("numready=%d\n",numready);
?? ??? ?for (i=0;nummonitor>0 && numready>0; i++)
?? ??? ?{
?? ??? ??? ?if((pollfd+i)->revents & POLLIN)
?? ??? ??? ?{
?? ??? ??? ??? ?
?? ??? ??? ? ?? ?bytes = read(pollfd[i].fd, buf, BUFSIZE);
?? ??? ??? ??? ?numready--;
?? ??? ??? ??? ?printf("pollfd[%d]->fd read buf:\n%s \n", i, buf);
?? ??? ??? ??? ?nummonitor--;
?? ??? ??? ?}
?? ??? ?}
?? ?}
?? ?for(i=0; i<nummonitor; i++)
?? ??? ?close(pollfd[i].fd);
?? ?free(pollfd);
?? ?return 0;
}
輸出結果:
總結
以上是生活随笔為你收集整理的Linux Socket poll的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 结构和类的区别
- 下一篇: 1313 质因数分解 2012年NOI