poll调用深入解析

 

poll调用深入解析 http://blog.csdn.net/zmxiangde_88/article/details/8099049

poll调用和select调用实现的功能一样,都是网络IO利用的一种机制。先看一下poll的调用形式

 

poll调用 

#include <poll.h>
int poll(struct pollfd fds[], nfds_t nfds, int timeout);

 

struct pollfd结构如下:【在源码文件poll.h文件中】

struct pollfd {
  int fd;
  short events;
  short revents;
};

 这个结构中fd表示文件描述符,events表示请求检测的事件,revents表示检测之后返回的事件,如果当某个文件描述符有状态变化时,revents的值就不为空。

 

二,参数说明

  1. fds:存放需要被检测状态的Socket描述符;与select不同(select函数在调用之后,会清空检测socket描述符的数组),每当调用这个函数之后,系统不会清空这个数组,而是将有状态变化的描述符结构的revents变量状态变化,操作起来比较方便;
  2. nfds:用于标记数组fds中的struct pollfd结构元素的总数量;
  3. timeout:poll函数调用阻塞的时间,单位是MS(毫秒)
三,返回值 
  1. 大于0:表示数组fds中有socket描述符的状态发生变化,或可以读取、或可以写入、或出错。并且返回的值表示这些状态有变化的socket描述符的总数量;此时可以对fds数组进行遍历,以寻找那些revents不空的socket描述符,然后判断这个里面有哪些事件以读取数据。
  2. 等于0:表示没有socket描述符有状态变化,并且调用超时。
  3. 小于0:此时表示有错误发生,此时全局变量errno保存错误码。

 

四、韦东山的按键中断驱动代码中,加入poll机制的示例:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <poll.h>


/* forthdrvtest 
  */
int main(int argc, char **argv)
{
    int fd;
    unsigned char key_val;
    int ret;

    struct pollfd fds[1];
    
    fd = open("/dev/buttons", O_RDWR);
    if (fd < 0)
    {
        printf("can't open!\n");
    }

    fds[0].fd     = fd;
    fds[0].events = POLLIN;
    while (1)
    {
        ret = poll(fds, 1, 5000);
        if (ret == 0)
        {
            printf("time out\n");
        }
        else
        {
            read(fd, &key_val, 1);
            printf("key_val = 0x%x\n", key_val);
        }
    }
    
    return 0;
}

 

韦东山jz2440 CD1\drivers_and_test\forth_drv中,一个字符设备要实现poll的功能,就在原来的的基础上,加了如下代码:


static
unsigned forth_drv_poll(struct file *file, poll_table *wait) { unsigned int mask = 0; poll_wait(file, &button_waitq, wait); // 不会立即休眠 if (ev_press) mask |= POLLIN | POLLRDNORM; return mask; } static struct file_operations sencod_drv_fops = { .owner = THIS_MODULE, /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */ .open = forth_drv_open, .read = forth_drv_read, .release = forth_drv_close, .poll = forth_drv_poll, };
button_waitq是驱动中定义的等待队列头 static DECLARE_WAIT_QUEUE_HEAD(button_waitq);

 

DECLARE_WAIT_QUEUE_HEAD()的说明 http://blog.csdn.net/commandow/article/details/5774587

  static DECLARE_WAIT_QUEUE_HEAD(button_waitq); 生成一个等待队列头wait_queue_head_t, 名字为button_waitq。

 

posted @ 2015-12-30 22:40  oucaijun  阅读(1057)  评论(0编辑  收藏  举报
下载TeamViewer完整版 下载TeamViewer