linux驅動---file_operations之poll

簡述:
file_operations的poll是驅動提供給應用程序探測設備文件是否有數據可讀接口。

應用程序探測文件的接口:
select,poll,epoll三個接口都是應用程序探測設備文件是否有數據可讀的接口,沒有數據進程阻塞,有數據時喚醒。select和poll差不多,epoll是select、poll的增強版,性能上會更好。

select頭文件:

#include <sys/select.h>

poll頭文件:

#include <sys/poll.h>

epoll頭文件:

#include <sys/epoll.h>

如是ubuntu系統,select.h、poll.h、epoll.h都可以在/usr/include/sys/目錄下查看。

三個函數詳細說明用法,參考如下博客:
Linux IO模式及 select、poll、epoll詳解
linux poll函數
Linux內核中select, poll和epoll的區別

驅動層實現file_operations的poll:

先直接看一個例子:

static DECLARE_WAIT_QUEUE_HEAD(my_waitq);  //休眠要掛的等待隊列
static unsigned drv_poll(struct file *file, poll_table *wait)
{
    unsigned int mask = 0;
    poll_wait(file, &my_waitq, wait); // 不會立即休眠
    if (有數據)//判斷是否有數據
    mask |= POLLIN | POLLRDNORM;
    return mask;
}

poll_wait:看得出,我們只是提供了一個waitqueue,沒有數據時進程會阻塞在這個waitqueue上。驅動poll裏面基本上都要用這個函數,定義在頭文件:

#include <linux/poll.h>

例子中,進程不會在drv_poll裏面阻塞,當mask爲0返回時,進程阻塞,什麼時候喚醒,需要驅動根據情況去wake up我們定義的waitqueue(my_waitq)。如有數據時,需要告訴系統數據情況,如例子中的mask |= POLLIN | POLLRDNORM,mask不爲0不阻塞,根據mask值做出操作。

POLLIN、POLLRDNORM宏定義在include/uapi/asm-generic/poll.h中,說明如下:
POLLIN: 有數據可讀。
POLLRDNORM: 有普通數據可讀。
POLLRDBAND:有優先數據可讀。
POLLPRI:有緊迫數據可讀。
POLLOUT:寫數據不會導致阻塞。表示有空間可寫。
POLLWRNORM:寫普通數據不會導致阻塞。表示有空間可寫。
POLLWRBAND:寫優先數據不會導致阻塞。表示有空間可寫。
POLLMSG:SIGPOLL 消息可用。
POLLER:指定的文件描述符發生錯誤。
POLLHUP:指定的文件描述符掛起事件。
POLLNVAL:指定的文件描述符非法。

總結:驅動接口poll不會阻塞進程,只是返回後,系統會根據返回值是否阻塞進程,如阻塞,需求驅動去喚醒(有數據時wake up)。

poll代碼跟蹤分析,參考如下博客:
linux的poll機制

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