第 13 章 IO操作模式_第1頁
第 13 章 IO操作模式_第2頁
第 13 章 IO操作模式_第3頁
第 13 章 IO操作模式_第4頁
第 13 章 IO操作模式_第5頁
已閱讀5頁,還剩42頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

第13章I/O操作模式內容提要

/O操作模式概述

POSIX異步I/OLinux本地異步I/O異步I/O信號驅動I/O多路復用高性能I/O事件驅動13.1I/O操作模式I/O操作模式概述

在Linux系統(tǒng)中,文件作為一個泛化的概念,廣泛存在于系統(tǒng)。雖然為文件定義了標準的I/O操作集,但具體實現取決于文件,不同類型的文件具有不同的行為特征。,它們實現的操作集也可能有所不同,如,具有異步特性的網絡套接字,慢速的磁盤設備等。當進程需要同時處理多個文件I/O時,基于阻塞的處理方式具有一定的局限性,為此,內核提供了多種非阻塞的處理方法。阻塞與非阻塞

從用戶的角度,對于向內核發(fā)起的I/O請求,發(fā)起者是否需要等待請求的完成,可將I/O模式分為阻塞與非阻塞。若發(fā)起者等待,直至I/O請求完成,則稱為I/O阻塞模式;若無論I/O請求是否完成,發(fā)起者立即返回,則稱為I/O非阻塞模式。同步與異步

從內核的角度,對于發(fā)起的I/O請求,內核是否需要發(fā)起者等待請求的完成,可將I/O模式分為同步I/O模式和異步I/O模式。若內核需發(fā)起者等待,直至I/O請求完成,則稱為I/O同步模式。若內核無須發(fā)起者等待,I/O請求完成時,內核以某種方式通知發(fā)起者,期間發(fā)起者可繼續(xù)執(zhí)行后續(xù)操作,則稱為I/O異步模式。異步I/O模式

對于需在一個進程中同時監(jiān)聽多個文件的I/O狀態(tài),內核提供了多種異步I/O處理模式,它們通常采用非阻塞模式。這些異步I/O方法包括。POSIX異步I/O本地異步I/O異步I/O信號驅動I/O多路復用高性能I/O事件驅動應用編程接口分類接口函數功能描述POSIX異步I/Oaio_read發(fā)起異步讀請求aio_write發(fā)起異步寫請求lio_listio提交多個異步I/O請求aio_cancel試圖取消異步I/O請求aio_return返回已完成的I/O狀態(tài)aio_error獲得異步I/O錯誤信息Linux本地異步I/Oio_setup創(chuàng)建異步I/O環(huán)境io_submit提交異步I/O請求io_getevents獲取已完成異步I/O請求io_cancel取消一個未完成的異步IO操作io_destro注銷異步I/O環(huán)境I/O多路復用select同時監(jiān)聽多個文件的I/O狀態(tài)poll同時監(jiān)聽多個文件的I/O狀態(tài)高性能I/O事件驅動epoll_create創(chuàng)建epoll環(huán)境epoll_ctl設置監(jiān)聽對象epoll_wait等待epoll實例上產生的I/O就緒事件13.2POSIX異步I/OPOSIX異步I/O概述POSIX為程序員提供了一組異步I/O編程接口,允許向內核發(fā)起一個或多個異步I/O請求,發(fā)起者無須等待I/O操作完成,繼續(xù)執(zhí)行后續(xù)操作,當異步I/O操作完成,內核以某種方式通知發(fā)起者,例如,發(fā)送信號或啟動線程等。Linux異步I/O的實現

POSIX異步I/O在Linux系統(tǒng)中以glibc函數庫方式實現,由于早期的內核不支持異步I/O,glibc利用線程處理異步I/O請求;自內核2.6起引入一組本地異步I/O系統(tǒng)調用接口,glibc對原異步I/O處理進行了重構,從根本上提高了異步I/O性能。值得注意的是,POSIX異步I/O僅適用于磁盤文件系統(tǒng)。發(fā)起異步讀/寫請求1.aio_read/aio_write函數頭文件

#include<aio.h>函數原型

int

aio_read(struct

aiocb*aiocbp)

int

aio_write(struct

aiocb*aiocbp)功能 發(fā)起異步讀/寫請求。參數

aiocbp:I/O請求。返回值 成功返回0,失敗返回-1。發(fā)起異步讀/寫請求(續(xù))(1)異步I/O請求struct

aiocb{

int

aio_fildes; //文件描述符

volatilevoid*aio_buf;//緩沖區(qū)地址

size_t

aio_nbytes; //讀/寫數據的字節(jié)數

off_t

aio_offset; //文件偏移量

int

aio_reqprio; //請求優(yōu)先級

struct

sigevent

aio_sigevent;//通知方式

int

aio_lio_opcode; //僅適用于lio_listio函數};(2)通知方式struct

sigevent{

int

sigev_notify;//通知方法

int

sigev_signo;//信號編號

unionsigval

sigev_value;//傳遞的數據

void(*sigev_notify_function)(unionsigval);//線程函數

void*sigev_notify_attributes;//線程屬性

pid_t

sigev_notify_thread_id;//線程ID};一次提交多個異步I/O請求2.lio_listio函數頭文件

#include<aio.h>函數原型

int

lio_listio(int

mode,struct

aiocb*constaiocb_list[],int

nitems,struct

sigevent*sevp);功能 一次提交多個異步I/O請求。參數

mode:提交模式。

aiocb_list:請求數組。

nitems:請求數量。

sevp:通知方式。返回值 所有I/O成功提交返回0,失敗返回-1。取消已提交的異步I/O請求3.aio_cancel函數頭文件

#include<aio.h>函數原型

int

aio_cancel(int

fd,struct

aiocb*aiocbp);功能 取消已提交的異步I/O請求。參數

fd:文件描述符。

aiocbp:異步I/O請求。返回值 若返回AIO_CANCELED,請求全部被取消。獲取異步I/O的返回值4.aio_return函數頭文件

#include<aio.h>函數原型

ssize_t

aio_return(struct

aiocb*aiocbp);功能 獲取異步I/O的返回值。參數

aiocbp:異步I/O請求。返回值

I/O請求完成,返回異步處理的字節(jié)數。

I/O請求失敗,返回-1。獲取異步I/O請求的當前狀態(tài)5.aio_error函數頭文件

#include<aio.h>函數原型

int

aio_error(const

struct

aiocb*aiocbp);功能 獲取異步I/O請求的當前狀態(tài)。參數

aiocbp:異步I/O請求。返回值 若返回EINPROGRESS,表示正在處理。 若返回ECANCELED,表示異步操作被取消。 如返回0,表示異步操作已完成。 若返回值小于零,表示發(fā)生錯誤。13.3Linux本地異步I/O本地異步I/O概述

為了提高磁盤I/O請求的處理效率,Linux自內核2.6起,引入一組非標準化的本地異步I/O接口。該組接口是glibc構造POSIX異步I/O的基礎。它由5個系統(tǒng)調用組成,glibc未對它們進行封裝,但可借助syscall函數實現對它們的訪問。創(chuàng)建/注銷異步I/O上下文頭文件

#include<linux/aio_abi.h>函數原型

io_setup(unsigned

nr_events,aio_context_t*ctx_idp);

int

io_destroy(aio_context_t

ctx_id);功能 創(chuàng)建/注銷異步I/O上下文。參數

nr_events:容納異步I/O請求的最大數量。

ctx_idp:異步I/O上下文。返回值 成功返回0,失敗返回非0。提交異步I/O請求頭文件

#include<linux/aio_abi.h>函數原型

longio_submit(aio_context_t

ctx_id,long

nr,struct

iocb**iocbpp)功能 提交異步I/O請求,參數

ctx_id:異步I/O上下文,

nr:異步I/O請求數量,

iocbpp:異步I/O請求數組,返回值 成功返回提交的請求數,失敗返回非0,提交異步I/O請求(續(xù))struct

iocb{__u64aio_data;//自定義參數

__u16aio_lio_opcode;//操作類型,IO_CMD_PWRITE,IO_CMD_PREAD__s16aio_reqprio;//請求的優(yōu)先級

__u32aio_fildes;//文件描述符

__u64aio_buf;//數據緩存區(qū)

__u64aio_nbytes;//請求字節(jié)數

__s64aio_offset;//偏移量

...};取消已提交的異步IO請求頭文件

#include<linux/aio_abi.h>函數原型

int

io_cancel(aio_context_t

ctx_id,struct

iocb*iocb,struct

io_event*result);io_event*result)功能 取消已提交的異步IO請求。參數

ctx_id:異步I/O上下文。

iocb:異步I/O請求。

result:返回消息。返回值 成功返回0,失敗返回非0。獲取已完成的異步I/O事件頭文件

#include<linux/aio_abi.h>函數原型

longio_getevents(aio_context_t

ctx_id,longmin_nr,longnr,struct

io_event*events,struct

timespec*timeout)功能 獲取已完成的異步I/O事件。參數

ctx_id:異步I/O上下文。

min_nr:請求完成的最小數量。

nr:請求完成的最大數量。

events:完成的I/O事件。

timeout:超時時間。返回值 成功返回事件數量,失敗返回值在0至min_nr之間。獲取已完成的異步I/O事件(續(xù))struct

io_event{__u64data;//對應iocb的aio_data

__u64obj;//產生event的iocb__s64res;//完成的字節(jié)數

__s64res2;//返回狀態(tài)};13.4異步I/O信號驅動異步I/O信號驅動概述

異步

I/O信號驅動是一種文件I/O狀態(tài)改變時的信號通知機制,默認向目標進程發(fā)送SIGIO信號。

對于I/O信號驅動的文件,通常設置為非阻塞模式,信號屬于邊緣觸發(fā)事件。

值得注意的是,并非所有文件都支持異步I/O信號。異步I/O信號的操作流程異步處理方式1.為文件定義I/O信號2.將文件設置為異步非阻塞模式3.設置信號的發(fā)送目標4.編寫信號的處理函數異步I/O信號的操作流程(續(xù))

同步處理方式1和2與異步處理方式相同。3.阻塞I/O信號4.以同步方式處理到達的I/O信號實時信號隊列的溢出處理

當眾多文件瞬間狀態(tài)發(fā)生改變時,內核會產生大量I/O信號,即使使用了實時信號,也可能導致信號隊列溢出。當I/O信號溢出時,新產生的I/O信號恢復為SIGIO,在處理SIGIO信號時,可使用sigwaitipfo函數盡快處理等待的信號,繼而使用select/poll函數處理剩余的I/O事件。13.5I/O多路復用內容提要1I/O多路復用概述基于select的I/O多路復用基于poll的I/O多路復用1I/O多路復用概述I/O多路復用是一種同時監(jiān)聽多個文件I/O狀態(tài)的技術,當有文件I/O狀態(tài)發(fā)生改變時,以I/O事件方式通知監(jiān)聽者。事件的產生采用水平觸發(fā)模式,只要I/O狀態(tài)可用,就一直產生I/O事件。

Linux繼承了Unix的select和poll兩種I/O多路復用接口?;趕elect的I/O多路復用

處于歷史原因select監(jiān)聽的文件受1024數量的限制,每次監(jiān)聽前都需將觀察文件信息從用戶空間拷貝至內核空間,監(jiān)聽時需掃描整個文件列表,以確定產生就緒I/O事件的文件,無疑增加了系統(tǒng)開銷。select函數頭文件

#include<sys/select.h> #include<sys/time.h>函數原型

int

select(int

nfds,fd_set*readfds,fd_set*writefds,fd_set*exceptfds,struct

timeval*timeout);功能 同時監(jiān)聽多個文件的I/O狀態(tài)。參數

nfds:監(jiān)聽的最大文件描述符。readfds:可讀文件描述符集。

writefds:可寫的文件描述符集。exceptfds:例外文件描述符集。

timeout:超時時間。返回值

>0,返回就緒事件的數量。=0,等待超時。-1,錯誤?;趐oll的I/O多路復用poll也是被廣泛支持的I/O多路復用接口,功能與select相似,盡管poll對檢查的文件數量沒有限制,但每次監(jiān)聽仍需復制和掃描整個文件描述符。poll函數頭文件

#include<sys/poll.h>函數原型

intpoll(struct

pollfd*fds,unsignedint

nfds,inttimeout);功能 同時監(jiān)聽多個文件的I/O狀態(tài)。參數

fds:監(jiān)聽對象數組地址。

nfds:監(jiān)聽文件數量。

timeout:超時時間,單位毫秒。返回值 成功:發(fā)生就緒事件的文件數量失敗:-1。poll函數(續(xù))struct

pollfd{int

fd;//文件描述符shortevents;//關注的事件shortrevents;//已發(fā)生的事件};事件類型含義POLLIN有數據可讀POLLPRI高優(yōu)先級數據可讀POLLOUT有數據可寫POLLRDHUP套接字對端關閉,Linux內核2.6.171版本之后POLLWRBAND優(yōu)先級數據可寫POLLERR發(fā)生錯誤POLLHUP發(fā)生掛起POLLNVAL文件描述符無效13.6高性能I/O事件驅動epoll概述

為了提高I/O多路復用的性能,Linux內核自2.6起,引入了一種高性能異步I/O事件處理的本地化接口,稱為epoll

epoll是對傳統(tǒng)I/O多路復用的優(yōu)化和擴展,無須每次設置和掃描整個被監(jiān)聽的文件,僅需一次性將需監(jiān)聽的被文件描述符注冊至內核,內核使用紅黑樹管理監(jiān)聽的對象,將用戶緩存映射至內核空間,提高了數據存取效率,使用鏈表管理產生的I/O就緒事件。事件觸發(fā)模式

epoll提供了水平觸發(fā)和邊緣觸發(fā)兩種事件觸發(fā)模式。1.水平觸發(fā)模式

只要文件的I/O狀態(tài)可用,便可產生對應的I/O事件。2.邊緣觸發(fā)模式只有文件的狀態(tài)與上一次相比發(fā)生了改變,才產生相應的I/O事件。創(chuàng)建epoll實例頭文件

#include<sys/epoll.h>函數原型

int

epoll_create(intsize);功能 創(chuàng)建epoll實例。參數

size:文件描述符的最大數量。返回值 成功返回rpoll文件描述符,失敗返回-1。設置監(jiān)聽對象頭文件

#include<sys/epoll.h>函數原型

int

epoll_ctl(int

epfd,int

op,int

fd,struct

epoll_event*event);功能 設置監(jiān)聽對象。參數

epfd:epoll實例。

Op:操作符。

fd:文件描述符。

event:事件。返回值 成功返回0,失敗返回-1。參數op定義EPOLL_CTL_ADD向epoll實例添加監(jiān)聽對象EPOLL_CTL_MOD修改epoll實例的監(jiān)聽對象EPOLL_CTL_DEL從epoll實例刪除監(jiān)聽對象epoll_ctl含住中參數op的定義I/O事件類型含義EPOLLIN接收到普通數據EPOLLPRI接收到緊急數據EPOLLRDHUP套接字對端關閉,Linux內核2.6.171版本之后EPOLLOUT可以寫入數據EPOLLET邊緣觸發(fā)EPOLLLT水平觸發(fā),缺省模式EPOLLONESHOT只監(jiān)聽一次事件EPOLLERR當描述符發(fā)生錯誤,默認設置E

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論