三种I/O多路复用机制学习记录----poll学习(1)
最近在准备一个面试,可能会问到三种I/O复用机制,但是大学学操作系统的上机都是水过来的,因此,现在正在补坑T-T,今天准备学习一下最基本的poll,我将记录自己理解的poll。
poll函数是什么
百度百科上说,poll是Linux中的字符设备驱动中的一个函数(这个字面上一点都不好理解,我们先继续学)首先我们来看一下这个系统调用函数的原型:
int poll(struct pollfd fdset[], nfds_t nfds, int timeout);
这个函数有三个入参:
- fdset: pollfd结构体数组,pollfd的结构体定义如下:
#include<poll.h>
struct pollfd{
int fd;/*文件描述符,如果小于0。这个文件描述符将会被进程忽略*/
short events;/*注册的事件,即感兴趣的事件。可以是一个事件,也可以是多个事件的按位或*/
short revents;/*实际发生的事件,由内核来赋值。需要与某种类型的事件按位与来确定某种事件是否发生*/
}
单看这个结构是不是有点懵,但是如果我们知道这些事件类型分为可读/可写/异常这三种,或许好理解一点,这个结构体指定了我们感兴趣的文件描述符上发生的可读可写和异常事件;
现在或许还是很懵,我们继续;
- nfds:该参数指定了pollfd结构体数组fdset的大小,nfds_t是一个无符号长整型类型:typedef unsigned long int nfds_t
- timeout:该参数指定poll的超时时间,单位是毫秒。
timeout == -1:永久等待,直到指定的描述符有事件发生或捕捉到信号时返回;
timeout == 0 :执行完描述符立刻返回;
timeout > 0 :在超时时间内,指定描述符有事件发生或捕捉到信号时返回。
poll的返回值:
返回值 > 0: 数组fdset已经准备好读写或异常事件的描述符的总数量;
返回值 == 0:在超时时间内没有任何描述符准备好了;
返回值 == -1:函数调用失败了。
poll实现的功能
在理解poll实现的功能到底是什么之前,我们有一个大前提,poll是一种I/O多路复用机制,那一定和读写有关了。先来看一个简单一点的例子:
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <poll.h>
int main(){
struct pollfd fdset[1];
fdset[0].fd = 0;
fdset[0].events = POLLIN | POLLERR;
int ret;
char buf[100];
while(1){
ret = poll(fdset, 1, -1);
if(ret <= 0)
{
printf("poll err! ret[%d]",ret);
break;
}
if(fdset[0].revents == POLLIN){
ret = read(0, buf, 100);
printf("读取到%d个字节的数据%s", ret, buf);
}
}
return 0;
}
这段代码实现的功能很容易理解:一旦有键盘输入便会触发POLLIN事件,然后我们读取从键盘输入的数据;一旦poll监听多个描述符,便可实现多路I/O。
poll的优缺点和应用场景,等我过完epoll和select之后整理总结。
poll先到这……
该文章主要学习链接:
https://blog.csdn.net/qq_37964547/article/details/80697530