select与poll的接口说明

在linux驱动中,有时候需要实现非阻塞的read和write操作,但用户不可能周期地去查询设备是否可读或可写吧,那在驱动中就需要实现poll接口,然后在应用层调用select系统调用。

在驱动中需要实现poll接口,其主要内容为通过poll_wait(读等待队列,wait)、poll_wait(写等待队列)将读、写等待队列添加到wait表中。注意:poll_wait()本身并不是阻塞的调用,真正的阻塞是应用层调用select()接口,poll()接口就是添加读、写等待队列,返回POLLIN或POLLOUT的状态。poll_wait()函数所做的工作是把当前进程添加到
wait 参数指定的等待列表(poll_table)中。通常在接收中断中根据某个接收条件调用wait_up_interruptible(读等待队列),而在发送中断中根据某个发送条件调用wait_up_interruptible(写等待队列)。那么有人就会问:如果一个线程只操作写,另一个线程只操作读,而由于poll()中添加了读与写的等待队列,两个条件中的一个都会唤醒select()去遍历监听的读、写文件set。如果接收产生了条件唤醒了select(),那是不是也会唤醒发送的那个线程呢?这就需要靠应用层在调用select()接口时的配置了。详细的调用如下图所示:

关于驱动中的poll_wait,它的作用就是把当前进程添加到wait参数指定的等待列表(poll_table)中。需要注意的是这个函数是不会引起阻塞。那如果poll_wait不阻塞,当应用层调用select()系统调用时,真正实现阻塞功能是哪里实现的呢?其实真正的阻塞是在应用层上的select接口函数中。

 

poll_wait()是用在select系统调用中的. 
一般你的代码会有一个struct file_operations结构, 
其中fop->poll函数指针指向一个你自己的函数, 
在这个函数里应该调用poll_wait() 

当用户调用select系统调用时,select系统调用会 
先调用 
poll_initwait(&table); 
然后调用你的 
fop->poll(); 
从而将current加到某个等待队列(这里调用poll_wait()), 
并检查是否有效 
如果无效就调用 
schedule_timeout(); 
去睡眠. 

事件发生后,schedule_timeout()回来,调用 
fop->poll(); 
检查到可以运行,就调用 
poll_freewait(&table); 

从而完成select系统调用. 

重要的是fop->poll()里面要检查是否就绪, 
如果是,要返回相应标志 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章