在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            EEPW首頁 > 嵌入式系統(tǒng) > 牛人業(yè)話 > Linux內(nèi)核開發(fā)之異步通知與異步I/O(三)

            Linux內(nèi)核開發(fā)之異步通知與異步I/O(三)

            作者: 時間:2016-12-19 來源:網(wǎng)絡 收藏

              小王,聽說過AIO沒?外國人,就這樣,總是愛簡寫,簡寫的結果是咱們都不認識了。所謂AIO就是Asynchronous Input/Output異步輸入/輸出,基本思想是允許進程發(fā)起很多的I/O操作,而不用阻塞或等待任何操作的完成,稍后或在接收到I/O操作完成的通知時,進程就可以檢索I/O操作的結果。

            本文引用地址:http://www.biyoush.com/article/201612/341754.htm

              “得得,你咋又跟我上起課來了呢,不是說好,今天CS嗎?是不是跟我講課特自信啊“小王抱怨到。

              “啊?不是吧,為啥這樣呢,那你到底聽不聽,別到時面試叫天天不靈叫地地不應的,別再找我哈”我氣憤的說。

              "唉,你都這樣說了,我也只能豎起耳朵好好聽聽了"看著小王極不情愿的表情,我也覺得很可憐啊。

              在異步非阻塞IO中,我們是可以同時發(fā)起多個傳輸操作。這需要每個操作都有一個唯一的上下文,這樣才能在它們完成時區(qū)分到底是哪個傳輸操作完成了。在AIO中,

              通過aiocb(AIO IO control Block)結構體進行區(qū)分,這個結構體如下:

              struct aiocb {

              int aio_fildes; /* File descriptor */

              off_t aio_offset; /* File offset */

              volatile void * aio_buf; /* Location of buffer */

              size_t aio_nbytes; /* Length of transfer */

              int aio_reqprio; /* Request priority offset */

              struct sigevent aio_sigevent; /* Signal number and value */

              int aio_lio_opcode; /* Operation to be performed */

              };

              從上邊我們可以看到,這個結構體包含了有關傳輸?shù)乃行畔?,包括?shù)據(jù)準備的用戶緩沖區(qū)。在產(chǎn)生IO通知時,aiocb結構就被用來唯一標識所完成的IO操作。

              AIO系列API中主要有下邊幾個函數(shù):

              1.int aio_read(struct aiocb *aiocbp)

              該函數(shù)請求對一個有效的文件描述符進行異步讀操作。在請求進行排隊之后會立即返回,如果執(zhí)行成功,返回值就為0,錯誤則返回-1并設置errno的值。

              2.int aio_write(struct aiocb *aiocbp)

              該函數(shù)請求一個異步寫操作,它會立即返回說明請求已經(jīng)進行排隊,成功返回0,失敗返回為-1,并設置相應的error值。

              3.int aio_error(struct aiocb *aiocbp)

              該函數(shù)用來確定請求的狀態(tài),可以返回EINPROGRESS(說明請求尚未完成),ECANCELLED(請求被應用程序取消了),-1(說明發(fā)生了錯誤,具體錯誤原因由error記錄)。

              4.ssize_t aio_return(struct aiocb *aiocbp)

              由于并沒有阻塞在read調(diào)用上,所以我們不能立即返回這個函數(shù)的返回狀態(tài),這是就要使用這個函數(shù)了,需要注意的是只有在aio_error調(diào)用確定請求已經(jīng)完成(可能

              已經(jīng)完成,也可能發(fā)生了錯誤)之后,才能調(diào)用這個函數(shù),這個函數(shù)的返回值就相當于同步情況下read或write系統(tǒng)調(diào)用的返回值(所傳輸?shù)淖止?jié)數(shù),如果發(fā)生錯誤,則返回-1)。

              5.int aio_suspend(const struct aiocb *const cblist[], int n ,const struct timespec *timeout)

              用戶可以通過這個函數(shù)來來掛起(或阻塞)調(diào)用進程,直到異步請求完成為止,此時會產(chǎn)生一個信號,或者發(fā)生其他超時操作。調(diào)用者提供了一個aiocb引用列表,其中任何一個完成都會導致給函數(shù)返回。

              6.int aio_cancel(int fd ,struct aiocb *aiocbp)

              該函數(shù)允許用戶取消對某個文件描述符執(zhí)行的一個或所有的IO請求。

              如果要取消一個請求,用戶需提供文件描述符和aiocb引用,如果這個請求被成功取消了,則返回AIO_CANCELED,如果該請求完成了,返回AIO_NOTCANCELED.

              如果要取消對某個給定文件描述符的所有請求,用戶需要提供這個文件的描述符以及一個aiocbp的NULL引用,如果所有請求被成功取消了,則返回AIO_CANCELED

              ,只要至少有一個沒被取消,這個函數(shù)就返回AIO_NOT_CANCELED.如果沒有一個請求可以被取消,該函數(shù)就會返回AIO_ALLDONE.

              然后,可以使用aio_error來驗證每個AIO請求,如果某個請求已經(jīng)被返回了,那么aio_error就返回-1,并且error會被設置為ECANCELED.

              7.int lio_listio(int mode ,struct aiocb *list[], int nent ,struct sigevent *sig)

              這個操作使得用戶可以在一個系統(tǒng)調(diào)用(一次內(nèi)核上下文切換中啟動大量的I/O操作)。其中,mode參數(shù)可以是LIO_WAIT或LIO_NOWAIT,前者會阻塞這個調(diào)用,直到所有的IO都完成為止,在操作進行排隊之后,LIO_NOWAIT就會返回,list是一個aiocb引用的列表,最大元素的個數(shù)有nent定義的。如果list的元素為NULL,lio_lis

              tio()將被忽略。

              光說理論也不行,是不?現(xiàn)在來點實際點的:

              a)用戶空間讀例程:

              #include 

              ..

              int fd, set;

              struct aiocb my_aiocb;

              fd = open("file.txt", O_RDONLY);

              if( fd <0 )

              {

              perror("open");

              }

              //清零aiocb結構體

              bzero((char *) &my_aiocb, sizeof(struct aiocb));

              //為aiocb請求分配數(shù)據(jù)緩沖區(qū)

              my_aiocb.aio_buf = malloc(BUFSIZE + 1);

              if(!my_aiocb.aio_buf)

              perror("malloc");

              //初始化aiocb的成員

              my_aiocb.aio_fildes = fd;

              my_aiocb.aio_nbytes = BUFSIZE;

              my_aiocb.aio_offset = 0;

              ret = aio_read(&my_aiocb);

              if(ret < 0)

              perror("aio_read");

              while(aio_error(&my_aiocb) == EINPROGRESS)

              ;

              if((ret = aio_return(&my_iocb)))

              {

              // 獲得異步讀的返回值

              }

              else

              {

              讀失敗,分析errror

              }

              b)用戶空間異步IO aio_suspend()函數(shù)使用例程

              struct aioct *cblist(MAX_LIST)

              //清零aioct結構鏈表

              bzero((char *)cblist, sizeof(cblist));

              //將一個或更多的aiocb放入aioct結構體鏈表

              cblist[0] = &my_aiocb;

              ret = aio_read( &my_aiocb);

              ret = aio_suspend( cblist, MAX_LIST, NULL);

              c)用戶空間異步IO lio_list()函數(shù)使用例程

              struct aiocb aiocb1,aiocb2;

              struct aiocb *list[MAX_LIST];

              ...

              //準備第一個aiocb

              aiocb1.aio_fildes = fd;

              aiocb1.aio_buf = malloc(BUFSIZE +1);

              aiocb1.aio_nbytes = BUFSIZE;

              aiocb1.aio_offset = next_offset;

              aiocb1.aio_lio_opcode = LIO_READ;//異步讀操作

              ...//準備多個aiocb

              bzero((char *)list, sizeof(list));

              //將aiocb填入鏈表

              list[0] = &aiocb1;

              list[1] = &aiocb2;

              ...

              ret = lio_listio(LIO_WAIT, list, MAX_LIST, NULL); //發(fā)起大量IO操作

              “濤哥,你說了這么多,好像也咋沒和你說的驅(qū)動扯上關系呢”小王抱怨道。

              “小王,不要急嗎,我不是正打算說嗎,瞧你著急性子,這樣吧,你把今天的好好看看,我們下集再說”…



            關鍵詞: Linux 異步通知

            評論


            相關推薦

            技術專區(qū)

            關閉