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

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第13章I/O操作模式內(nèi)容提要

/O操作模式概述

POSIX異步I/OLinux本地異步I/O異步I/O信號(hào)驅(qū)動(dòng)I/O多路復(fù)用高性能I/O事件驅(qū)動(dòng)13.1I/O操作模式I/O操作模式概述

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

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

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

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

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

#include<aio.h>函數(shù)原型

int

aio_read(struct

aiocb*aiocbp)

int

aio_write(struct

aiocb*aiocbp)功能 發(fā)起異步讀/寫(xiě)請(qǐng)求。參數(shù)

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

aiocb{

int

aio_fildes; //文件描述符

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

size_t

aio_nbytes; //讀/寫(xiě)數(shù)據(jù)的字節(jié)數(shù)

off_t

aio_offset; //文件偏移量

int

aio_reqprio; //請(qǐng)求優(yōu)先級(jí)

struct

sigevent

aio_sigevent;//通知方式

int

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

sigevent{

int

sigev_notify;//通知方法

int

sigev_signo;//信號(hào)編號(hào)

unionsigval

sigev_value;//傳遞的數(shù)據(jù)

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

void*sigev_notify_attributes;//線程屬性

pid_t

sigev_notify_thread_id;//線程ID};一次提交多個(gè)異步I/O請(qǐng)求2.lio_listio函數(shù)頭文件

#include<aio.h>函數(shù)原型

int

lio_listio(int

mode,struct

aiocb*constaiocb_list[],int

nitems,struct

sigevent*sevp);功能 一次提交多個(gè)異步I/O請(qǐng)求。參數(shù)

mode:提交模式。

aiocb_list:請(qǐng)求數(shù)組。

nitems:請(qǐng)求數(shù)量。

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

#include<aio.h>函數(shù)原型

int

aio_cancel(int

fd,struct

aiocb*aiocbp);功能 取消已提交的異步I/O請(qǐng)求。參數(shù)

fd:文件描述符。

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

#include<aio.h>函數(shù)原型

ssize_t

aio_return(struct

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

aiocbp:異步I/O請(qǐng)求。返回值

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

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

#include<aio.h>函數(shù)原型

int

aio_error(const

struct

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

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

為了提高磁盤(pán)I/O請(qǐng)求的處理效率,Linux自內(nèi)核2.6起,引入一組非標(biāo)準(zhǔn)化的本地異步I/O接口。該組接口是glibc構(gòu)造POSIX異步I/O的基礎(chǔ)。它由5個(gè)系統(tǒng)調(diào)用組成,glibc未對(duì)它們進(jìn)行封裝,但可借助syscall函數(shù)實(shí)現(xiàn)對(duì)它們的訪問(wèn)。創(chuàng)建/注銷(xiāo)異步I/O上下文頭文件

#include<linux/aio_abi.h>函數(shù)原型

io_setup(unsigned

nr_events,aio_context_t*ctx_idp);

int

io_destroy(aio_context_t

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

nr_events:容納異步I/O請(qǐng)求的最大數(shù)量。

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

#include<linux/aio_abi.h>函數(shù)原型

longio_submit(aio_context_t

ctx_id,long

nr,struct

iocb**iocbpp)功能 提交異步I/O請(qǐng)求,參數(shù)

ctx_id:異步I/O上下文,

nr:異步I/O請(qǐng)求數(shù)量,

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

iocb{__u64aio_data;//自定義參數(shù)

__u16aio_lio_opcode;//操作類(lèi)型,IO_CMD_PWRITE,IO_CMD_PREAD__s16aio_reqprio;//請(qǐng)求的優(yōu)先級(jí)

__u32aio_fildes;//文件描述符

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

__u64aio_nbytes;//請(qǐng)求字節(jié)數(shù)

__s64aio_offset;//偏移量

...};取消已提交的異步IO請(qǐng)求頭文件

#include<linux/aio_abi.h>函數(shù)原型

int

io_cancel(aio_context_t

ctx_id,struct

iocb*iocb,struct

io_event*result);io_event*result)功能 取消已提交的異步IO請(qǐng)求。參數(shù)

ctx_id:異步I/O上下文。

iocb:異步I/O請(qǐng)求。

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

#include<linux/aio_abi.h>函數(shù)原型

longio_getevents(aio_context_t

ctx_id,longmin_nr,longnr,struct

io_event*events,struct

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

ctx_id:異步I/O上下文。

min_nr:請(qǐng)求完成的最小數(shù)量。

nr:請(qǐng)求完成的最大數(shù)量。

events:完成的I/O事件。

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

io_event{__u64data;//對(duì)應(yīng)iocb的aio_data

__u64obj;//產(chǎn)生event的iocb__s64res;//完成的字節(jié)數(shù)

__s64res2;//返回狀態(tài)};13.4異步I/O信號(hào)驅(qū)動(dòng)異步I/O信號(hào)驅(qū)動(dòng)概述

異步

I/O信號(hào)驅(qū)動(dòng)是一種文件I/O狀態(tài)改變時(shí)的信號(hào)通知機(jī)制,默認(rèn)向目標(biāo)進(jìn)程發(fā)送SIGIO信號(hào)。

對(duì)于I/O信號(hào)驅(qū)動(dòng)的文件,通常設(shè)置為非阻塞模式,信號(hào)屬于邊緣觸發(fā)事件。

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

同步處理方式1和2與異步處理方式相同。3.阻塞I/O信號(hào)4.以同步方式處理到達(dá)的I/O信號(hào)實(shí)時(shí)信號(hào)隊(duì)列的溢出處理

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

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

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

#include<sys/select.h> #include<sys/time.h>函數(shù)原型

int

select(int

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

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

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

writefds:可寫(xiě)的文件描述符集。exceptfds:例外文件描述符集。

timeout:超時(shí)時(shí)間。返回值

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

#include<sys/poll.h>函數(shù)原型

intpoll(struct

pollfd*fds,unsignedint

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

fds:監(jiān)聽(tīng)對(duì)象數(shù)組地址。

nfds:監(jiān)聽(tīng)文件數(shù)量。

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

pollfd{int

fd;//文件描述符shortevents;//關(guān)注的事件shortrevents;//已發(fā)生的事件};事件類(lèi)型含義POLLIN有數(shù)據(jù)可讀POLLPRI高優(yōu)先級(jí)數(shù)據(jù)可讀POLLOUT有數(shù)據(jù)可寫(xiě)POLLRDHUP套接字對(duì)端關(guān)閉,Linux內(nèi)核2.6.171版本之后POLLWRBAND優(yōu)先級(jí)數(shù)據(jù)可寫(xiě)POLLERR發(fā)生錯(cuò)誤POLLHUP發(fā)生掛起POLLNVAL文件描述符無(wú)效13.6高性能I/O事件驅(qū)動(dòng)epoll概述

為了提高I/O多路復(fù)用的性能,Linux內(nèi)核自2.6起,引入了一種高性能異步I/O事件處理的本地化接口,稱(chēng)為epoll

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

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

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

#include<sys/epoll.h>函數(shù)原型

int

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

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

#include<sys/epoll.h>函數(shù)原型

int

epoll_ctl(int

epfd,int

op,int

fd,struct

epoll_event*event);功能 設(shè)置監(jiān)聽(tīng)對(duì)象。參數(shù)

epfd:epoll實(shí)例。

Op:操作符。

fd:文件描述符。

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

溫馨提示

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

評(píng)論

0/150

提交評(píng)論