非阻塞(轮询)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()的补充与优化.




相关文章推荐

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

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

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

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

轮询操作 (select poll)

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

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

接上一篇文章,以poll函数实现并发请求。通过上一篇的测试我们ke'zhi

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

用select函数实现服务器的并发处理

linux编程——I/O操作之文件阻塞|非阻塞

阻塞、非阻塞 读常规文件是不会阻塞的,不管读多少字节,read一定会在有限的时间内返回。从终端设备或网络读则不一定,如果从终端输入的数据没有换行符,调用read读终端设备就会阻塞,如果网络上没有接收...

内核轮询式IO(poll-select)

驱动层 static ssize_t fifo_read (struct file *f, char __user *p, size_t n, loff_t *off) { int size; i...

linux中的轮询机制select/poll/epoll

参考:StephenChan's Tech Space http://www.cnblogs.com/xuxm2007/archive/2011/08/15/2139809.html http:/...
  • paomadi
  • paomadi
  • 2013年05月23日 12:46
  • 5224

【unix网络编程第三版】阅读笔记(五):I/O复用:select和poll函数

本博文主要针对UNP一书中的第六章内容来聊聊I/O复用技术以及其在网络编程中的实现 1. I/O复用技术I/O多路复用是指内核一旦发现进程指定的一个或者多个I/O条件准备就绪,它就通知该进程。I/O复...

apue I/O多路转接,select与poll

I/O多路转接select传向select的参数告诉内核: 我们所关心的描述符。 对于每个描述符,我们所关心的状态(是否读一个给定的描述符?是否写一个给定的描述符?是否关心一个描述符的异常状态?)。 ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:非阻塞(轮询)I/O操作poll()和select()
举报原因:
原因补充:

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