自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

異步IO:新時代的IO處理利器

開發(fā) 前端
無論是非阻塞IO,IO復(fù)用,還是信號驅(qū)動式IO,都不是真正意義上的IO,真正的異步IO是數(shù)據(jù)從內(nèi)核空間拷貝到用戶空間也是異步處理的,拷貝完成,再通知應(yīng)用進程,應(yīng)用進程直接讀取用戶空間的數(shù)據(jù)進行操作。

[[374757]]

無論是非阻塞IO,IO復(fù)用,還是信號驅(qū)動式IO,都不是真正意義上的IO,真正的異步IO是數(shù)據(jù)從內(nèi)核空間拷貝到用戶空間也是異步處理的,拷貝完成,再通知應(yīng)用進程,應(yīng)用進程直接讀取用戶空間的數(shù)據(jù)進行操作。

到目前為止,我們介紹了阻塞IO,非阻塞IO,信號驅(qū)動式IO,IO復(fù)用,我們打個形象的比方,來對這幾種IO做下區(qū)分。

我們?nèi)ゾW(wǎng)上買東西,下完單之后,你可以有如下幾種處理方式:

  • 下完單之后,在門口一直等待快遞小哥把快遞送上門,這就是同步阻塞IO;
  • 下完單之后就不管了,直到快遞小哥打電話給你通知你去取快遞,這就是同步非阻塞IO里面的信號驅(qū)動式IO;
  • 下完單之后,你定時的去物流app上面查看你所有快遞的狀態(tài),只要有快遞送到了寄存點,你就去取,這就是同步非阻塞IO里面的IO復(fù)用;
  • 下完單之后,你就不管了,直到快遞小哥給你送上門,你直接拿到了快遞,你不用出門就可以拿到快遞了,這就是異步IO。

異步IO最關(guān)鍵的一點就是在讀取數(shù)據(jù)的時候,將IO的buffer提交給內(nèi)核,讓內(nèi)核往這個buffer寫數(shù)據(jù)。

這節(jié)我們就來介紹下異步IO模型和相關(guān)API,并且順便介紹下當下最新的更高性能的IO模型。

閱讀完本文,你將了解到:

  • 異步IO的原理;
  • POSIX下定義的異步IO接口以及使用方式;
  • 異步IO的發(fā)展方向。

1、異步I/O模型介紹

下面是異步IO(asynchronous I/O)的執(zhí)行流程流程:

通過異步處理函數(shù)如aio_read告知內(nèi)核啟動某個動作,并且讓內(nèi)核在整個操作完成之后再通知應(yīng)用進程,內(nèi)核會在把數(shù)據(jù)復(fù)制到用戶空間緩沖區(qū)之后再進行通知。整個IO過程應(yīng)用進程都不會被阻塞。

異步IO最大的優(yōu)化點在于:系統(tǒng)調(diào)用是昂貴的,異步IO將輪訓(xùn)等待數(shù)據(jù)的系統(tǒng)調(diào)用(如select,poll,epoll)和讀取數(shù)據(jù)操作合并起來。

下面我們就通過具體了例子來演示下異步IO程序的處理流程。

2、異步IO相關(guān)函數(shù)使用案例

本節(jié)我們介紹下POSIX定義的異步操作接口。

2.1、異步IO相關(guān)API

每個異步函數(shù)都需要傳入一個aiocb結(jié)構(gòu)(異步IO控制塊),這個結(jié)構(gòu)格式如下:

  1. struct aiocb { 
  2.   /* The order of these fields is implementation-dependent */ 
  3.   int             aio_fildes;     /* File descriptor */ 
  4.   off_t           aio_offset;     /* File offset */ 
  5.   volatile void  *aio_buf;        /* Location of buffer */ 
  6.   size_t          aio_nbytes;     /* Length of transfer */ 
  7.   int             aio_reqprio;    /* Request priority */ 
  8.   struct sigevent aio_sigevent;   /* Notification method */ 
  9.   int             aio_lio_opcode; /* Operation to be performed; 
  10.                                                   lio_listio() only */ 
  11.   /* Various implementation-internal fields not shown */ 
  12. }; 

該結(jié)構(gòu)體指定了要異步操作的套接字描述符,操作過程中用到的緩沖,其中aio_sigevent告訴AIO在IO操作完成時,應(yīng)該指向什么操作。

常見的異步IO相關(guān)函數(shù)如下:

INT AIO_READ(STRUCT AIOCB *AIOCBP)

請求異步讀操作,該函數(shù)將aiocbp指向的緩沖區(qū)描述的I/O請求排隊。

注意:aio_read的aiocbp中一定要設(shè)置偏移量

在傳統(tǒng)的非異步read操作中,偏移量是在文件描述符上下文進行維護的,對于每個操作,偏移量都需要更新,以便后續(xù)的操作可以對下一塊數(shù)據(jù)進行尋址。

而對于異步read操作來說,可以同時執(zhí)行很多異步IO read操作,所以這里需要的指明處理的文件的偏移量aiocbp->aio_offset和異步讀取的內(nèi)容的長度aiocbp->aio_nbytes。

aio_read調(diào)用后,文件偏移量變?yōu)槲丛O(shè)置。

INT AIO_WRITE(STRUCT AIOCB *AIOCBP)

請求異步寫操作,該函數(shù)將aiocbp指向的緩沖區(qū)描述的I/O請求排隊。

aio_write不一定要設(shè)置偏移量

如果打開的文件,設(shè)置了O_APPEND選項,那么偏移量就會被忽略,數(shù)據(jù)會被附加到文件的末尾;如果未設(shè)置O_APPEND,那么從aiocbp->aio_offset開始寫入數(shù)據(jù),而不考慮文件的偏移量。

SSIZE_T AIO_RETURN(STRUCT AIOCB *AIOCBP)

獲取完成的異步請求的返回狀態(tài)。

由于IO異步化了,需要有專門的函數(shù)來獲取異步處理的狀態(tài)。

aio_return的返回值即相當于read或write等系統(tǒng)調(diào)用的返回值。如果出錯,則返回-1,并正確設(shè)置errno。

可能的響應(yīng)值:

  • 成功后,將返回處理的字節(jié)數(shù);
  • -1:發(fā)生錯誤,并且設(shè)置errno以指示錯誤原因;

只有在aio_error調(diào)用返回EINPROGRESS之外的值之后,才可以調(diào)用這個函數(shù),并且只允許調(diào)用一次。

INT AIO_ERROR(CONST STRUCT AIOCB *AIOCBP)

檢查異步請求的狀態(tài),可能的響應(yīng)值:

  • EINPROGRESS:如果請求還沒有完成;
  • ECANCELED:如果請求已經(jīng)被取消;
  • 0:如果請求已完成;
  • 如果異步IO操作失敗,則為一個正數(shù)的error number,與同步的read(2), write(2), fsync(2),或者 or fdatasync(2)系統(tǒng)的errorno一致。

AIO_SUSPEND

  1. int aio_suspend(const struct aiocb * const aiocb_list[], 
  2.                        int nitems, const struct timespec *timeout); 

掛起調(diào)用進程,直到一個或者多個異步請求完成或失敗。

aiocb_list中存放需要等待的異步請求,如:

  1. struct aioct *cblist[MAX_LIST]; 
  2. ... 
  3. cblist[0] = &aiocb1; 
  4.  
  5. ret = aio_read( my_aiocb1 ); 
  6. ret = aio_suspend( cblist, MAX_LIST, NULL ); 

INT AIO_CANCEL(INT FD, STRUCT AIOCB *AIOCBP)

取消異步IO請求。

LIO_LISTIO

  1. int lio_listio(int mode, struct aiocb *const aiocb_list[], 
  2.                       int nitems, struct sigevent *sevp); 

發(fā)起一系列的IO操作,啟動數(shù)組aiocb_list描述的I/O操作列表。

下面通過具體例子展示aio的用法。

2.2、aio_read例子

如下是一個使用aio_read的例子:

我把重要的處理步驟都標注起來了,并在代碼中做了說明,這里不重復(fù)描述,需要注意幾點:

  • aio_read的aiocbp中一定要設(shè)置偏移量;
  • 一定要在調(diào)用aio_error,并且返回值不是EINPROGRESS之后,才調(diào)用aio_return后去異步IO處理狀態(tài)。

以上就是目前異步IO API的設(shè)計和基本使用方法。

3、操作系統(tǒng)對異步IO的支持情況

3.1、Linux下的異步IO

上一節(jié)介紹了POSIX下定義的異步操作接口,但是可惜Linux的aio操作不是真正的操作系統(tǒng)級別的支持,而是在用空間中借由GNU庫函數(shù)由pthread方式實現(xiàn)的,沒有對套接字IO進行支持。

基于以上原因,Linux下面,大部分還是通過使用epoll多路復(fù)用技術(shù),以及非阻塞IO,通過事件分發(fā)模型來構(gòu)建高性能網(wǎng)絡(luò)程序。

3.2、Windows下的異步IO

Windows實現(xiàn)了一套稱為IOCP(I/O Completion Ports,IO完成端口)[1]的完整的異步編程接口。IOCP提供了一種有效的線程模型,用于在多處理器系統(tǒng)上處理多個異步I / O請求。

當進程創(chuàng)建IOCP時,系統(tǒng)會為請求創(chuàng)建關(guān)聯(lián)的隊列對象,其唯一目的是為這些請求提供服務(wù)。

一個進程通過將IOCP與預(yù)分配的線程池結(jié)合使用,來處理許多并發(fā)異步IO請求,相比于通過在接收IO請求時創(chuàng)建線程,會更快,更高效。

基于IOCP,產(chǎn)生了Proactor模式,一種與Reactor模式類似,但是更加高效的模式。

這里是不是看的有點不太懂,沒關(guān)系,在后續(xù)高性能網(wǎng)絡(luò)編程范式章節(jié)中,我們會詳細介紹這兩種模式。

4、更高效的IO

4.1、背景

由于Linux下并沒有廣泛被采用的AIO技術(shù),aio系列的函數(shù)是有POSIX定義的異步操作接口,并不是真正操作系統(tǒng)內(nèi)核支持的異步IO。

目前最流行的還是基于epoll的多路復(fù)用技術(shù),以及依托多路復(fù)用技術(shù)產(chǎn)生的Reactor模式。

為了推動AIO在Linux系統(tǒng)的發(fā)展,實現(xiàn)更加高效的IO,于是后來變有了io_uring。

4.2、io_uring

io_uring是在Linux Kernel 5.1中添加的,用于替代AIO和io_submit,構(gòu)造通用的異步系統(tǒng)調(diào)用接口。

關(guān)于異步IO就介紹到這里,在下一篇文章中,我們會詳細探討使用各種IO模型的高性能網(wǎng)絡(luò)編程范式。

博客鏈接:https://www.itzhai.com

 

責(zé)任編輯:武曉燕 來源: Java架構(gòu)雜談
相關(guān)推薦

2023-12-06 07:28:47

阻塞IO異步IO

2023-04-12 18:36:20

IO框架內(nèi)核

2024-07-09 08:07:37

Go性能工具

2011-12-13 12:32:54

JavaNIO

2015-10-28 14:45:35

ORACLE AIO異步IO

2023-12-28 11:24:29

IO系統(tǒng)請求

2015-10-28 17:39:04

ORACLE AIO異步IO

2020-03-23 14:55:47

數(shù)據(jù)分析諸葛io

2023-08-01 08:43:29

Python多線程

2021-06-21 11:11:29

LinuxIO磁盤IO

2014-12-09 14:07:50

2021-06-18 09:17:10

探究Node前端開發(fā)

2018-10-08 15:35:56

Python異步IO

2021-09-30 07:26:15

磁盤IO網(wǎng)絡(luò)

2025-03-18 08:10:00

iodump開源I/O

2015-03-30 20:56:55

SaaS云計算企業(yè)級應(yīng)用

2024-01-15 14:39:45

以太網(wǎng)網(wǎng)絡(luò)電纜PoE系統(tǒng)

2011-01-10 10:27:51

linux應(yīng)用

2025-02-03 09:53:42

點贊
收藏

51CTO技術(shù)棧公眾號