<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Linux 原生異步 IO 原理與使用(Native AIO)

          共 3017字,需瀏覽 7分鐘

           ·

          2021-03-23 17:30

          什么是異步 IO?

          異步 IO:當(dāng)應(yīng)用程序發(fā)起一個(gè) IO 操作后,調(diào)用者不能立刻得到結(jié)果,而是在內(nèi)核完成 IO 操作后,通過(guò)信號(hào)或回調(diào)來(lái)通知調(diào)用者。

          異步 IO 與同步 IO 的區(qū)別如 圖1 所示:

          從上圖可知,同步 IO 必須等待內(nèi)核把 IO 操作處理完成后才返回。而異步 IO 不必等待 IO 操作完成,而是向內(nèi)核發(fā)起一個(gè) IO 操作就立刻返回,當(dāng)內(nèi)核完成 IO 操作后,會(huì)通過(guò)信號(hào)的方式通知應(yīng)用程序。

          Linux 原生 AIO 原理

          Linux Native AIO 是 Linux 支持的原生 AIO,為什么要加原生這個(gè)詞呢?因?yàn)長(zhǎng)inux存在很多第三方的異步 IO 庫(kù),如 libeioglibc AIO。所以為了加以區(qū)別,Linux 的內(nèi)核提供的異步 IO 就稱為原生異步 IO。

          很多第三方的異步 IO 庫(kù)都不是真正的異步 IO,而是使用多線程來(lái)模擬異步 IO,如 libeio 就是使用多線程來(lái)模擬異步 IO 的。

          本文主要介紹 Linux 原生 AIO 的原理和使用,所以不會(huì)對(duì)其他第三方的異步 IO 庫(kù)進(jìn)行分析,下面我們先來(lái)介紹 Linux 原生 AIO 的原理。

          如 圖2 所示:

          Linux 原生 AIO 處理流程:

          • 當(dāng)應(yīng)用程序調(diào)用 io_submit 系統(tǒng)調(diào)用發(fā)起一個(gè)異步 IO 操作后,會(huì)向內(nèi)核的 IO 任務(wù)隊(duì)列中添加一個(gè) IO 任務(wù),并且返回成功。

          • 內(nèi)核會(huì)在后臺(tái)處理 IO 任務(wù)隊(duì)列中的 IO 任務(wù),然后把處理結(jié)果存儲(chǔ)在 IO 任務(wù)中。

          • 應(yīng)用程序可以調(diào)用 io_getevents 系統(tǒng)調(diào)用來(lái)獲取異步 IO 的處理結(jié)果,如果 IO 操作還沒完成,那么返回失敗信息,否則會(huì)返回 IO 處理結(jié)果。

          從上面的流程可以看出,Linux 的異步 IO 操作主要由兩個(gè)步驟組成:

          • 1) 調(diào)用 io_submit 函數(shù)發(fā)起一個(gè)異步 IO 操作。

          • 2) 調(diào)用 io_getevents 函數(shù)獲取異步 IO 的結(jié)果。

          下面我們主要分析,Linux 內(nèi)核是怎么實(shí)現(xiàn)異步 IO 的。

          Linux 原生 AIO 使用

          在介紹 Linux 原生 AIO 的實(shí)現(xiàn)之前,先通過(guò)一個(gè)簡(jiǎn)單的例子來(lái)介紹其使用過(guò)程:

          #define _GNU_SOURCE
          #include <stdlib.h>#include <string.h>#include <libaio.h>#include <errno.h>#include <stdio.h>#include <unistd.h>#include <fcntl.h>
          #define FILEPATH "./aio.txt"
          int main(){ io_context_t context; struct iocb io[1], *p[1] = {&io[0]}; struct io_event e[1]; unsigned nr_events = 10; struct timespec timeout; char *wbuf; int wbuflen = 1024; int ret, num = 0, i;
          posix_memalign((void **)&wbuf, 512, wbuflen);
          memset(wbuf, '@', wbuflen); memset(&context, 0, sizeof(io_context_t));
          timeout.tv_sec = 0; timeout.tv_nsec = 10000000;
          int fd = open(FILEPATH, O_CREAT|O_RDWR|O_DIRECT, 0644); // 1. 打開要進(jìn)行異步IO的文件 if (fd < 0) { printf("open error: %d\n", errno); return 0; }
          if (0 != io_setup(nr_events, &context)) { // 2. 創(chuàng)建一個(gè)異步IO上下文 printf("io_setup error: %d\n", errno); return 0; }
          io_prep_pwrite(&io[0], fd, wbuf, wbuflen, 0); // 3. 創(chuàng)建一個(gè)異步IO任務(wù)
          if ((ret = io_submit(context, 1, p)) != 1) { // 4. 提交異步IO任務(wù) printf("io_submit error: %d\n", ret); io_destroy(context); return -1; }
          while (1) { ret = io_getevents(context, 1, 1, e, &timeout); // 5. 獲取異步IO的結(jié)果 if (ret < 0) { printf("io_getevents error: %d\n", ret); break; }
          if (ret > 0) { printf("result, res2: %d, res: %d\n", e[0].res2, e[0].res); break; } }
          return 0;}

          上面通過(guò)一個(gè)簡(jiǎn)單的例子來(lái)展示了 Linux 原生 AIO 的使用過(guò)程,主要有以下步驟:

          • 通過(guò)調(diào)用 open 系統(tǒng)調(diào)用打開要進(jìn)行異步 IO 的文件,要注意的是 AIO 操作必須設(shè)置 O_DIRECT 直接 IO 標(biāo)志位。

          • 調(diào)用 io_setup 系統(tǒng)調(diào)用創(chuàng)建一個(gè)異步 IO 上下文。

          • 調(diào)用 io_prep_pwrite 或者 io_prep_pread 函數(shù)創(chuàng)建一個(gè)異步寫或者異步讀任務(wù)。

          • 調(diào)用 io_submit 系統(tǒng)調(diào)用把異步 IO 任務(wù)提交到內(nèi)核。

          • 調(diào)用 io_getevents 系統(tǒng)調(diào)用獲取異步 IO 的結(jié)果。

          在上面的例子中,我們獲取異步 IO 操作的結(jié)果是在一個(gè)無(wú)限循環(huán)中進(jìn)行的,其實(shí) Linux 還支持一種基于 eventfd 事件通知的機(jī)制,可以通過(guò) eventfdepoll 結(jié)合來(lái)實(shí)現(xiàn)事件驅(qū)動(dòng)的方式來(lái)獲取異步 IO 操作的結(jié)果,有興趣可以查閱相關(guān)的內(nèi)容。

          總結(jié)

          本文主要介紹了 Linux 原生 AIO 的原理和使用,Linux 原生 AIO 的使用比較簡(jiǎn)單,但其內(nèi)部實(shí)現(xiàn)比較復(fù)雜,在下篇文章中將會(huì)介紹 Linux 原生 AIO 的實(shí)現(xiàn)。


          瀏覽 97
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  精品91视频 | 日本无码在线看 | 欧美一级黄片在线 | MD-0127 艾秋 分享骚货老婆 强势调教处男晚辈 | 免费在线AⅤ视频 |