IO多路復用輪詢

2021-07-25 05:16:54 字數 4348 閱讀 5178

receive(), fget(), read()等函式都是阻塞讀。

對於運用層:

將所有等待的輸入事件都進行監控,只要其中乙個就緒,就往下走,乙個都沒有就緒就一直等(也可設定超時),

此時監控池只知道「反正至少有乙個就緒了,具體是誰並不知道」。

往下走時用if分支對所有的監控物件(輸入事件)進行輪詢,看究竟是哪乙個就緒。

對於核心層(驅動):

光運用層使用select()、poll()、epoll()而底層沒有與之相配合的阻塞機制那是不奏效的,所以驅動必須要有相對應的函式配合。

對於驅動而言:既然我是被監控的物件,那我沒資料可讀(或者沒空間可寫)時得上報,有資料可讀(或者有空間可寫)時也得通知

一下運用層,不然poll()、epoll()怎麼知道我就緒了。

驅動層中這個機制是操作方法集中的乙個函式介面的實現(與open同級),這個過程中用到的最重要的函式就是poll_wait().

通知運用層的方式是return mask,這個mask會攜帶是否就緒的資訊。

select() ,poll() , epoll(),

只告訴應用層:「反正是有人產生了事件了,可以來處理了,

但具體是誰產生了什麼事我根本不知道,你再去乙個個問吧」

/*

* 功能:

* 輸入引數:__nfds: 最大檔案描述符加1

* fd_set * __readfds: 讀集

* fd_set * __writefds: 寫集

* fd_set * __exceptfds: 異常集

* struct timeval *__timeout: 超時時間(0表示永不超時,即阻塞)

*/int

select (int __nfds, fd_set *__restrict __readfds,

fd_set *__restrict __writefds,

fd_set *__restrict __exceptfds,

struct timeval *__restrict __timeout);

/*

* 功能: 將檔案描述符加到監控池

*/fd_set(int fd, fdset *set)

/*

* 功能: 清空監控池

*/fd_zero(fdset *set)

/*

* 功能: 將某個檔案描述符從監控池中刪除

*/fd_clr(int fd, fdset *set)

/*

* 功能: 檢查監控池中某個檔案描述符是否有事件就緒

*/fd_isset(int fd, fdset *set)

只告訴應用層:「反正是有人產生了事件了,可以來處理了,

我可以告訴你是寫事件還是讀事件,但具體是誰產生了,你再去乙個個問吧」。

它用陣列管理物件,避免了select要與fd_set等函式配合的繁瑣步驟,

並且相比select至少可以從renents中知道是寫還是讀,

加入監控池之前也可以選擇events是監控寫還是監控讀。

/*

* 其中乙個形參的型別說明

*/struct pollfd

/*

* 功能: 監控池

* 輸入引數:struct pollfd *fds:監控結構的首位址

* nfds_t nfds: 陣列長度

* int timeout: 超時時間(0表示永不超時,即阻塞)

*/int poll(struct pollfd *fds, nfds_t nfds, int timeout);

時間效率高,但空間效率低。

他不僅知道有事件產生,還把產生的是誰,是什麼事件放在renvents中供使用者查詢。

告訴應用層說:「有人產生事件了,

我已經將產生這個事件的人和產生的什麼事件放到revents中了,

人髒俱獲,請君檢視」

typedef

union epoll_data epoll_data_t;

struct epoll_event ;
/*

* 功能:建立乙個監控池

* 輸入引數: size:監控池大小,最多監控幾項

* 返回值:epoll的控制代碼(相當於檔案描述符)

*/int epoll_create(int

size);

/*

* 功能:對epoll的屬性進行設定

* 輸入引數:int epfd: epoll的控制代碼

* int op: 命令選項,epoll_ctl_add增,epoll_ctl_del刪,epoll_ctl_mod切換為輸入/輸出

* int fd: 要監控的使用者檔案描述符

* struct epoll_event *event: 使用者要監控的事件是輸入還是輸出

*/int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

/*

* 功能:監控,等待事件發生,

* 輸入引數:epfd: epoll控制代碼

* maxevents: 最大描述符夾1

* timeout: 超時時間(0永不超時)

* 輸出引數:struct epoll revents:反饋回來的事件,就緒的是輸入/還是輸出

io多路復用例項分析.doc

我寫的乙個基於epoll多路復用的socket伺服器端,支援乙太網卡各項引數的查詢與修改

struct file_operations {

struct module *owner;

loff_t (*llseek) (struct file *, loff_t, int);

ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);

ssize_t (*write) (struct file *, const

char __user *, size_t, loff_t *);

unsigned

int (*poll) (struct file *, struct poll_table_struct *); //io多路復用的函式介面

long (*unlocked_ioctl) (struct file *, unsigned

int, unsigned

long);

...

/*

* 功能:向poll_table中註冊等待佇列

* 輸入引數:filp: 上層傳進來的檔案控制代碼

* queue:等待佇列

* wait: 監控列表

* 返回值:none

見另一篇部落格,將poll操作方法及等待佇列的:

等待佇列

更詳細的解釋見部落格:

I O多路復用

一 五種i o模型 1 阻塞i o模型 最流行的i o模型是阻塞i o模型,預設情形下,所有套介面都是阻塞的。我們以資料報套介面為例來講解此模型 我們使用udp而不是tcp作為例子的原因在於就udp而言,資料準備好讀取的概念比較簡單 要麼整個資料報已經收到,要麼還沒有。然而對於tcp來說,諸如套介面...

i o多路復用

最常見的i o多路復用就是 select poll epoll了,下面說說他們的一些特點和區別吧。select 可讀 可寫 異常三種檔案描述符集的申明和初始化。fd set readfds,writefds,exceptionfds fd zero readfds fd zero writefds ...

I O多路復用

我們都知道unix like 世界裡,一切皆檔案,而檔案是什麼呢?檔案就是一串二進位製流而已,不管socket,還是fifo 管道 終端,對我們來說,一切都是檔案,一切都是流。在資訊 交換的過程中,我們都是對這些流進行資料的收發操作,簡稱為i o操作 input and output 往流中讀出資料...