<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

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

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

作者: 時(shí)間:2016-12-19 來(lái)源:網(wǎng)絡(luò ) 收藏

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

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

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

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

  "唉,你都這樣說(shuō)了,我也只能豎起耳朵好好聽(tīng)聽(tīng)了"看著(zhù)小王極不情愿的表情,我也覺(jué)得很可憐啊。

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

  通過(guò)aiocb(AIO IO control Block)結構體進(jìn)行區分,這個(gè)結構體如下:

  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 */

  };

  從上邊我們可以看到,這個(gè)結構體包含了有關(guān)傳輸的所有信息,包括數據準備的用戶(hù)緩沖區。在產(chǎn)生IO通知時(shí),aiocb結構就被用來(lái)唯一標識所完成的IO操作。

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

  1.int aio_read(struct aiocb *aiocbp)

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

  2.int aio_write(struct aiocb *aiocbp)

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

  3.int aio_error(struct aiocb *aiocbp)

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

  4.ssize_t aio_return(struct aiocb *aiocbp)

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

  已經(jīng)完成,也可能發(fā)生了錯誤)之后,才能調用這個(gè)函數,這個(gè)函數的返回值就相當于同步情況下read或write系統調用的返回值(所傳輸的字節數,如果發(fā)生錯誤,則返回-1)。

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

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

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

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

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

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

  ,只要至少有一個(gè)沒(méi)被取消,這個(gè)函數就返回AIO_NOT_CANCELED.如果沒(méi)有一個(gè)請求可以被取消,該函數就會(huì )返回AIO_ALLDONE.

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

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

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

  tio()將被忽略。

  光說(shuō)理論也不行,是不?現在來(lái)點(diǎn)實(shí)際點(diǎn)的:

  a)用戶(hù)空間讀例程:

  #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請求分配數據緩沖區

  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)用戶(hù)空間異步IO aio_suspend()函數使用例程

  struct aioct *cblist(MAX_LIST)

  //清零aioct結構鏈表

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

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

  cblist[0] = &my_aiocb;

  ret = aio_read( &my_aiocb);

  ret = aio_suspend( cblist, MAX_LIST, NULL);

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

  struct aiocb aiocb1,aiocb2;

  struct aiocb *list[MAX_LIST];

  ...

  //準備第一個(gè)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;//異步讀操作

  ...//準備多個(gè)aiocb

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

  //將aiocb填入鏈表

  list[0] = &aiocb1;

  list[1] = &aiocb2;

  ...

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

  “濤哥,你說(shuō)了這么多,好像也咋沒(méi)和你說(shuō)的驅動(dòng)扯上關(guān)系呢”小王抱怨道。

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



關(guān)鍵詞: Linux 異步通知

評論


相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>