143 POLL机制基本概念

一、简介

  • poll机制的底层实现原理就是基于等待队列来实现的。

  • poll()函数,用户空间可以调用之
    file_operations->poll,最终会调用操作接口的这个指针

二、应用层 poll()函数相关

1、异步阻塞型IO

  • 同步阻塞
    应用层调用一个(read/write)对一个文件进行读写操作时,read/write 可能使当前的进程或者线程进入一个休眠态,就是进程/线程阻塞在一个文件的读写操作上(read\write),陷入休眠态的进程/线程只能通过对应的文件设备驱动唤醒自己

  • 异步阻塞
    在应用层调用poll函数时发生, poll会对多个文件进行轮询操作,去查看每一个文件是否有特定的事件。
    若所有文件上都未发生特定的事件,那么poll函数会阻塞当前的进程或者线程。
    poll文件涉及多个文件的轮询,所以poll函数引起的进程或者线程休眠,可以被多个设备驱动唤醒。多个文件就对应多个设备驱动。
    阻塞在多个文件的轮询操作上(poll),可被多个设备驱动唤醒

  • 文件I/O事件类型(常见)
    可读、可写、异常…
    (poll函数的目的就是查询每个文件的io事件,没查到就会引起休眠)
    这些事件是由设备驱动产生的,产生后会唤醒由poll函数导致的进程或者线程休眠,poll函数也能把发生的事件返回给用户空间。

2、poll函数

#include <poll.h>

功能:监视多个文件描述符的指定事件(注意是指定事件,不是所有事件),事件发生时(驱动唤醒poll函数导致休眠的进程线程),把发生的具体事件通知给用户程序

// 参数1:fds数组类型详见下
// 参数2:nfds:pollfd数组的元素个数,要监控的文件描述符数量
// 参数3:timeout:超时时间(ms),不希望进程线程一直休眠在poll函数里
int poll(struct pollfd *fds,nfds_t nfds,int timeout)
struct pollfd
{
	// 要监视的文件描述符
	int fd;
	// 指定要监视的请求事件类型,通过设置一系列的宏来描述
  	short events; /* 请求的事件类型 */
  	// revents是返回事件,内核设置具体的返回事件,记录实际发生的事件
 	short revents; /* 返回的事件类型 */
};
  • events 是要监视的事件
    POLLIN:系统内核通知应用层指定数据已经备好,读数据不会被阻塞
    POLLPRI :有紧急的数据需要读取
    POLLOUT :系统内核通知应用层IO缓冲区已准备好,写数据不会被阻塞
    POLLERR :指定的文件描述符发生错误,必须先解决错误,才能对文件作其他的处理。
    POLLNVAL:无效的请求

  • 返回值:
    成功:发生事件的文件数量,超时返回0
    失败:-1

三、测试程序

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <poll.h>

int main(int argc, char *argv[])
{
    int ret;
    // yiweizhe suoyouchengyuan
    struct pollfd fds = {0};
    fds.fd = 0;
    fds.events = POLLIN;

    ret = poll(&fds, 1, 5000);
    printf("%s(%d):ret=%d\n", __FILE__, __LINE__, ret);
    if(ret == -1)
    {
        printf("%s(%d):poll error\n", __FILE__, __LINE__);
    }
    else if(ret)
    {
        printf("%s(%d):%d files ready\n", __FILE__, __LINE__, ret);
    }
    else
    {
        printf("%s(%d):timeout\n", __FILE__, __LINE__);
    }
    return 0;
}

四、测试现象

/lib/modules/4.1.15 # ./app &
/lib/modules/4.1.15 # app.c(16):ret=0
app.c(27):timeout

[1]+  Done                       ./app
/lib/modules/4.1.15 # 
/lib/modules/4.1.15 # 
/lib/modules/4.1.15 # ./app &
/lib/modules/4.1.15 # cat 
1
app.c(16):ret=1
app.c(23):1 files ready
1

应该是可以通过单独的cat来向标准输入传递数据。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值