功能:针对大量描述符进行监控
函数接口:
- int poll(struct pollfd *fds, nfds_t nfds, int timeout);
参数说明:
fds:pollfd结构体数组
cs
struct pollfd {
Int fd;// 要监控的描述符
short events;// 该描述符要监控的事件
short revents;//poll监控返回时设置的实际就绪事件
};
事件宏:POLLIN-可读;POLLOUT-可写;
异常事件:POLLHUP-挂断;POLLERR-出错;POLLNVAL-无效请求 POLLRDHUP-连接半关闭(对端关闭了读)
额外知识点:
网络通信程序,编写的时候都需首先忽略SIGPIPE信号,tcp对端关闭了连接,或者关闭了读操作,继续send写入数据就会触发SIGPIPE异常,导致异常退出。
signal(SIGPIPE, SIG_IGN);
Tcp连接断开之后,继续recv就会返回0不在阻塞;继续send就会触发SIGPIPE异常
nfds:fds数组的有效元素数量
timeout:监控阻塞超时时间(毫秒)
-1:阻塞直到有就绪
0:非阻塞
>0:指定阻塞时间
返回值:
<0:出错
==0:超时
>0:实际就绪的描述符数量
(1)操作流程:
1.定义描述符事件结构体数组(数组的大小根据实际场景确定)
2.将需要监控的描述符以及所要监控的事件,添加到数组中
3.发起poll监控调用
a.监控原理与select 并无差别
b.现将数组数据,拷贝到内核中
c.对所有的有效元素进行遍历,判断是否有就绪
i. 有就绪则直接返回,并且设置对应元素的revents成员
ii. 没有就绪的,就阻塞进程
iii.当有描述符就绪的时候,唤醒进程阻塞,再次遍历数组,重置revents成员
- 调用返回后,遍历数组,根据数组中的revent确定实际就绪的事件进行IO操作
大代码流程:
实现一个简单的poll使用样例
对标准输入进行可读事件监控,就绪了则读取数据进行打印
cpp
/*
实现一个简单的poll使用样例
对标准输入进行可读事件监控,就绪了则读取数据进行打印
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/poll.h>
int main(){
//1. 定义描述符事件结构数组
size_t size = 0;
struct pollfd fds[1024];
//2. 向数组中添加描述符以及要监控的事件
fds[size].fd = 0;
fds[size].events = POLLIN;
size += 1;
while(1) {
int ret = poll(fds, size, 3000);
if (ret < 0) {
perror("poll error");
continue;
}else if (ret == 0) {
printf("timeout\n");
continue;
//4.遍历数组,对就绪的描述符进行实际就绪事件的处理
for (int i = 0; i < size; i++) {
if (fds[i].revents & POLLIN) {
//就绪了可读事件
char buffer[1024] = {0};
read(fds[i].fd, buffer, 1023);
printf("读取的到数据:%s\n",buffer);
}
}
}
return 0;
}