i o多路復用筆記

2022-04-29 17:51:11 字數 2818 閱讀 5511

作業系統的核心是核心,獨立於普通的應用程式,可以訪問受保護的記憶體空間,也可以訪問底層硬體裝置。為了保護使用者程序不能直接操作核心,保證核心的安全,作業系統將虛擬空間劃分為兩部分,一部分是核心空間,一部分是使用者空間。

核心掛起當前正在cpu上執行的程序,並恢復以前掛起的某個程序的執行。

正在執行的程序,由於期待某些事件的發生,比如io,自動執行阻塞原語,進入阻塞狀態。這是一種主動行為,只有執行中的程序才可以切換到阻塞狀態。在阻塞狀態的程序是不占用cpu資源的。

標準i/o,資料會先被拷貝到作業系統的核心緩衝區,然後才會從作業系統的核心緩衝區拷貝到應用程式的位址空間。

linux有五種網路模式:

1、阻塞i/o

使用者程序呼叫recvfrom系統呼叫,程序進入阻塞狀態,等待資料準備好,資料會從核心拷貝到使用者記憶體,然後核心返回結果,使用者程序解除block狀態,重新執行。

2、非阻塞i/o

使用者程序呼叫read操作,如果資料還沒準備好,核心立刻返回error,使用者程序不會阻塞。使用者程序可以通過反覆呼叫read操作輪詢來獲得資料。

3、i/o多路復用

i/o multiplexing,也就是select、poll、epoll,也可以被稱為event driven i/o。好處是單個程序可以處理多個網路i/o,原理就是select、poll、epoll這個function會不斷的輪詢所負責的所有socket,當某個socket有資料到達時,就通知使用者程序。

使用者程序呼叫了select,整個程序會被block,同時,kernel會監聽所有負責的socket,當有乙個socket的資料準備好了,select會返回,使用者程序再呼叫read操作,將資料從核心拷貝到使用者程序。如果處理的併發連線數不是很高,使用select、poll、epoll的服務端效能不一定比使用multi-threading + blocking io的服務端效能好。i/o多路復用時,每乙個socket,一般設定為非阻塞模式。

int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
select函式監視的檔案描述符分3類,分別是readfds、writefds、exceptfds。呼叫select函式會阻塞,直到有描述符就緒或者超時,函式返回。當select函式返回後,可以通過遍歷fdset,找到就緒的描述符。

select可以良好的跨平台。缺點是單個程序能夠監視的檔案描述符的數量存在最大限制。在linux上一般為1024,可以通過修改巨集定義甚至重新編譯核心的方式提公升這一限制。

int poll(struct pollfd *fds, unsigned int nfds, int timeout)

struct pollfd

pollfd結構包含了要監視的event和發生的event,不再使用select『引數-值』傳遞的方式。pollfd沒有最大數量限制,但仍需要輪詢返回的pollfd來獲取就緒的檔案描述符。隨著監視的檔案描述符數量的增長,效率也會線性下降。

int epoll_create(int size)
建立乙個epoll的控制代碼,size用來告訴核心監聽的數目。size並不是限制了epoll所能監聽的最大描述符個數,只是對核心初始分配內部資料結構的乙個建議。

int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
函式對指定描述符fd執行op操作。op取值由三個巨集表示:新增epoll_ctl_add,刪除epoll_ctl_del,修改epoll_ctl_mod。epoll_event告訴核心需要監聽什麼事。

typedef union epoll_data  epoll_data_t;

struct epoll_event ;

//epoll events

epollin:表示對應的檔案描述符可讀(包括對端socket正常關閉)

epollout: 表示對應的檔案描述符可寫

epollpri: 表示對應的檔案描述符有緊急資料可讀(帶外資料)

epollerr: 表示對應的檔案描述法發生錯誤

epollhup: 表示對應的檔案描述法被掛起

epollet: 設定為邊緣觸發

epolloneshot: 只監聽一次事件,當監聽完這次事件後,如果還需要監聽這個socket,需要再次把這個socket加入epoll

int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout)
引數events表示核心得到的事件的集合。maxevents告知核心這個events有多大,取值不能大於建立epoll_create()時的size。引數timeout時超時時間(ms,0表示立刻返回,-1表示不確定,也有說法是永久堵塞)。該函式返回需要處理的事件數目,如返回0表示已超時。

兩種:lt(level trigger), et(edge trigger)。預設是lt。

lt是預設工作模式,支援block和non-block socket。et是高速工作模式,只支援non-block。

在select/poll中,程序只有在呼叫一定的方法後,核心才對所有監視的檔案描述符進行掃瞄。epoll事先通過epoll_ctl()來註冊乙個檔案描述符,一旦基於某個檔案描述符就緒時,核心會採用類似callback的**機制,迅速啟用這個檔案描述符,當程序呼叫epoll_wait()時便得到通知。epoll監視的描述符的數量不受限制,它所支援的fd上限是系統最大可開啟檔案數目。

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 往流中讀出資料...