poll
接口流程介绍:
int poll(struct pollfd* fds, nfds_t nfds, int timeout);
fds: 要监控的描述符事件结构体
struct poll{ int nfds; //要监控的描述符 short events; //想要监控的事件 short revents; //实际就绪的事件}
events: POLLIN----可读 POLLOUT----可写
revents:当poll接口调用返回的时候,这个描述符实际就绪的事件就会被写入revents中,程序员通过这个成员进行判断
nfds:第一个参数描述符事件结构体数量
timeout:超时等待事件----毫秒
返回值:返回值大于0表示就绪的描述符个数,返回值=0表示监控超时,返回值<0表示监控出错
流程:
1.定义描述符事件结构体数组,将需要监控描述符以及对应的事件信息填充到数组中
eg:struct pollfd fds[10]; fds[0].fd = 0; fds[0].events=POLLN | POLLOUT;----对标准输入监控可读事件以及可写事件
2.发起监控调用poll,将数组中数据拷贝到内核中进行轮询遍历监控,有描述符就绪或者超时等待后返回,返回时将这个描述符就绪的事件填充到对应结构体的revents中(如果描述符就绪,则revents中的数据为0)
3.监控调用返回后,程序员在程序中遍历数组中每个节点的revents确定当前节点的描述符就绪了什么事件,进而进行对应操作
#include<poll.h>
#include<unistd.h>
#include <stdio.h>
int main(){
struct pollfd poll_fd;
poll_fd.fd = 0;
poll_fd.events = POLLIN;
for(; ;){
int ret = poll(&poll_fd, 1, 1000);
if(ret < 0){
perror("poll");
continue;
}
if(ret == 0){
printf("poll timeout\n");
continue;
}
if(poll_fd.revents == POLLIN){
char buf[1024] = {
0};
read(0, buf, sizeof(buf)-1);
printf("stdin:%s", buf);
}
}
}
优缺点分析:
1.poll通过描述符事件结构体的方式简化了select的三种描述符集合的操作流程
2.poll所能监控的描述符,没有了最大数量限制(要监控多少描述定义多大数组即可)
3.poll每次监控不需要重新定义事件结构体
1.监控原理是在内核中进行轮询判断,会随着描述符的增多而性能下降
2.无法跨平台移植
3.每次监控调用返回后也需要程序员在程序中进行遍历判断才能知道哪个描述符就绪了哪个事件
4.依然每次需要将数组拷贝到内核中监控
5.监控的超时等待事件最精细到毫秒
epoll:linux下最好的多路转接模型
接口流程介绍:
1.在内核中创建eventpoll结构体,返回一个描述符作为代码中