非阻塞(轮询)I/O操作poll()和select()

原创 2013年12月05日 20:46:32

    除了阻塞之外,内核还提供了非阻塞(即轮询)策略.具体的程序表现为poll、select和epoll系统调用.上层应用程序最常见的是select()函数.而对应的底层函数即为poll()函数.

1.poll()简介:

    poll()函数原型如下:

unsigned int (*poll)(struct file *filp,poll_table *wait)
    各参数如下:

filp:对应用户空间打开的文件描述符;
wait:内核自动填充的,目前"拿来主义"即可.

2.poll()函数的实际使用:

    在驱动实现poll()函数,只需要下面两点即可达到目的:

1).将程序里面的队列头加入wait队列;
2).根据实际的设备情况返回掩码.
    其中,第1)步是通过函数poll_wait()实现的.其原型如下:

void poll_wait(struct file *,wait_queue_head_t *,poll_table *);
   第一个参数是用户空间打开的文件描述符;第二个参数是我们驱动自定义的等待队列头;第三个参数内核自动填充.

    上述第2)步对应的掩码见<linux/poll.h>,其掩码对于poll()的调用的意义是返回设备的情况,如数据是否就绪完毕.


3.实例:

    在poll()系统调用中,对应的用户空间的函数一般是select()函数,底层是poll()函数.如下:

    UserSpace:

    ret = select(fd + 1, &rds, NULL, NULL, NULL);
    if (ret < 0)    {
        printf("select error!\n");
        exit(1);
    }
    if (FD_ISSET(fd, &rds))
        read(fd, Buf, sizeof(Buf));
    select()会调用到底层的poll()函数,通过返回的掩码会知道是否有数据可读,如果有数据可读,即进行读数据动作.

    KernelSpace:

unsigned int mem_poll(struct file *filp, poll_table *wait)
{
    struct mem_dev  *dev = filp->private_data;
    unsigned int mask = 0;

    poll_wait(filp, &dev->inq,  wait);


    if (have_data)         mask |= POLLIN | POLLRDNORM;

    return mask;
}
    可见,驱动里面的poll()实现很清晰分两步走:一是加入wait队列;二是根据具体情况返回相应的掩码.


4.读数据之poll()和read():

    read()函数是比较重要级的函数,当输入缓冲区有数据,就算还不完整完全的数据,read()函数的返回也会有所延迟;当缓冲区没数据时,read()会阻塞,除非设置了O_NONBLOCK,而poll()只是汇报了数据的状态.


5.写数据之poll()和write():

    当写数据的时候,输出缓冲区已满的情况下,write()会阻塞,除非标志了O_NONBLOCK.而poll()会报告文件不可写.


6.poll()的意义:

    poll()比较轻量级,它可以立即向用户空间汇报底层设备的情况,上层可以根据其返回值而对数据的读写时机进行把握,是对write()和read()的补充与优化.




五种I/O 模式——阻塞(默认IO模式),非阻塞(常用语管道),I/O多路复用(IO多路复用的应用场景),信号I/O,异步I/O

五种I/O 模式: 【1】        阻塞 I/O           (Linux下的I/O操作默认是阻塞I/O,即open和socket创建的I/O都是阻塞I/O) 【2】        ...
  • suwei19870312
  • suwei19870312
  • 2014年03月07日 17:04
  • 1226

阻塞、非阻塞、异步、同步以及select/poll和epoll

针对IO,总是涉及到阻塞、非阻塞、异步、同步以及select/poll和epoll的一些描述,那么这些东西到底是什么,有什么差异? 一般来讲一个IO分为两个阶段: 等待数据到达把数据从内核空间拷贝...
  • lcx46
  • lcx46
  • 2014年12月18日 16:32
  • 8099

关于同步,异步,阻塞,非阻塞,IOCP/epoll,select/poll,AIO ,NIO ,BIO的总结

IO基本概念Linux环境Linux的内核将所有外部设备都可以看做一个文件来操作。那么我们对与外部设备的操作都可以看做对文件进行操作。我们对一个文件的读写,都通过调用内核提供的系统调用;内核给我们返回...
  • chen8238065
  • chen8238065
  • 2015年09月09日 13:52
  • 2549

Linux阻塞与非阻塞I/O之poll与select

轮询操作  轮询操作的概念与作用:   使用非阻塞I/O的应用程序通常会使用select()和poll()系统调用查询是否可对设备进行无阻塞的   访问。select()和poll()系统调...
  • gotosola
  • gotosola
  • 2012年03月27日 22:20
  • 1172

【Linux驱动】轮询操作select()和poll()

使用非阻塞I/O的应用程序通常会使用select()和poll()系统调用查询可对设备进行无阻塞的访问。select()和poll()系统调用最终会引发设备驱动中的poll()函数被执行。 sele...
  • yeswenqian
  • yeswenqian
  • 2015年12月12日 15:27
  • 1341

轮询操作 (select poll)

原文地址:http://blog.csdn.net/unbutun/article/details/4722448 L轮询函数 轮询的概念和作用 使用非阻塞I/O的应用程序通常会使用sele...
  • kangear
  • kangear
  • 2012年10月05日 15:42
  • 1320

linux驱动开发--字符设备:设备轮询操作select/poll

select系统调用         用于多路监控,当没有一个文件满足要求时,select调用将引起进程阻塞 设备轮询操作,对应select系统调用         unsigned int(*...
  • waldmer
  • waldmer
  • 2014年01月24日 15:31
  • 2370

I/O非阻塞函数实践:poll

接上一篇文章,以poll函数实现并发请求。通过上一篇的测试我们ke'zhi
  • u014507230
  • u014507230
  • 2014年06月04日 15:38
  • 407

I/O非阻塞函数实践:select

用select函数实现服务器的并发处理
  • u014507230
  • u014507230
  • 2014年06月04日 14:45
  • 452

I/O模型:从阻塞到非阻塞再到select

经过对网络模型的一段时间的学习,现在对I/O模型做出下列总结; 一般情况下,I/O操作一般包括两个阶段: (1)等待数据进入内核缓冲区;     (2)从内核的缓冲区往进程中拷贝数据。 1:阻塞模型:...
  • qq_27926751
  • qq_27926751
  • 2017年12月02日 18:11
  • 33
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:非阻塞(轮询)I/O操作poll()和select()
举报原因:
原因补充:

(最多只允许输入30个字)