使用非阻塞IO的应用程序通常使用Select Poll系统调用查询是否可以对设备进行无阻塞的访问。用户程序中用到最多的是select()


int select(int numfds,fd_set*readfds,fd_set *writefds,fd_set *errorfds,struct timeval *timeout);

fd_set *readfds,fd_set*writefds,fd_set *errorfds 为被监控的读,写,异常文件描述符集合

struct fd_set可以理解为一个集合,这个集合中存放的是文件描述符(file descriptor)


typedef struct {

      unsignedlong fds_bits [__FDSET_LONGS];

} __kernel_fd_set;

#define __FDSET_LONGS   (__FD_SETSIZE/__NFDBITS)

可以得知fds_bts为一个长度为16unsigned long类型数组。


对文件描述符集的操作。

1. 清零:FD_ZERO(&rfds);

#define __FD_ZERO(fdsetp) \

             (memset(fdsetp, 0, sizeof (*(fd_set *)(fdsetp))))


2. 将文件描述符加入到文件描述符集中

FD_SET(fd, fd_set *set)

#define __FD_SET(fd, fdsetp) \

             (((fd_set*)(fdsetp))->fds_bits[(fd) >> 5] |= (1<<((fd) & 31)))


3.将文件描述符从文件描述符集中删除

#define __FD_CLR(fd, fdsetp) \

             (((fd_set*)(fdsetp))->fds_bits[(fd) >> 5] &= ~(1<<((fd) & 31)))


4.判断文件描述符是否置位

#define __FD_ISSET(fd, fdsetp) \

             ((((fd_set*)(fdsetp))->fds_bits[(fd) >> 5] & (1<<((fd) & 31))) !=0)


设备驱动中的poll操作:

返回是否能对设备进行无阻塞的读,写掩码

Unsigned int(int* poll) (struct file* filp,struct poll_table* wait)

Poll函数模板:

Static unsigned int xxx_poll(struct file*filp, poll_table *wait)

{

Unsigned intmask = 0;

Struct xxx_dev*dev = file->private_data;

Poll_wait(filp,&dev->r_wait, wait); //把当前进程添加到wait的等待列表中,如果没有它会怎样。


Poll_wait(filp,&dev->w_wait, wait);

If(readable)

{

   Mask |= POLLIN | POLLRDNORM;

}

If(writeable)

{

   Mask |= POLLOUT| POLLRDNORM;

}

Return mask;

}


typedef void (*poll_queue_proc)(struct file*, wait_queue_head_t *, struct poll_table_struct *);

typedef struct poll_table_struct {

      poll_queue_procqproc;

      unsignedlong key;

} poll_table;


为什么要有poll_wait函数调用呢,不用可以不?


具体可以查阅:

http://wenku.baidu.com/view/330d42145f0e7cd18425361a.html