新聞中心

        EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > Linux內(nèi)核開(kāi)發(fā)之異步通知與異步I/O(五)

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

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

          “小王呢,今天開(kāi)始講AIO與設(shè)備驅(qū)動(dòng),這也是設(shè)備驅(qū)動(dòng)通知與異步IO的最后一節(jié)了,下次咱們就要開(kāi)始講更高級(jí)的東西,比如中斷啦,時(shí)鐘等”

        本文引用地址:http://www.104case.com/article/201612/342072.htm

          在內(nèi)核中,每個(gè)IO請(qǐng)求都對(duì)應(yīng)一個(gè)kiocb結(jié)構(gòu)體,其ki_filp成員指向?qū)?yīng)的file指針,通過(guò)is_sync_kiocb可以判斷某Kiocb時(shí)候?yàn)橥絀O請(qǐng)求,如果非真,表示是異步IO請(qǐng)求。

          塊設(shè)備和網(wǎng)絡(luò)設(shè)備本身就是異步的。只有字符設(shè)備驅(qū)動(dòng)必須明確指出應(yīng)支持AIO.需要說(shuō)明的是AIO對(duì)于大多數(shù)字符設(shè)備而言都不是必須的。只有少數(shù)才需要。

          在字符設(shè)備驅(qū)動(dòng)程序中,file_operations包含了3個(gè)和AIO相關(guān)的函數(shù)。如下:

          ssize_t (*aio_read) (struct kiocb *iocb, char *buffer, size_t count ,loff_t offset);

          ssize_t (*aio_write) (struct kiocb *iocb, const char *buffer, size_t count ,loff_t offset);

          int (*aio_fsync) (struct kiocb *iocb, int datasync);

          aio_read()和aio_write()與file_operation中的read()和write()中的offset參數(shù)不同,它直接傳遞值,而后者傳遞的是指針。這兩個(gè)函數(shù)本身也不一定完成讀寫(xiě)操作,它只是發(fā)起,初始化讀寫(xiě)操作。

          下面來(lái)看看實(shí)際的代碼部分:

          //異步讀

          static ssize_t xxx_aio_read(struct kiocb *iocb, char *buffer, size_t count ,loff_t offset)

          {

          return xxx_defer_op(0, iocb, buf, count, pos);

          }

          //異步寫(xiě)

          static ssize_t xxx_aio_write(struct kiocb *iocb, const char *buffer, size_t count ,loff_t offset)

          {

          return xxx_defer_op(1, iocb, (char *)buf, count, pos);

          }

          //初始化異步IO

          static int xxx_defer_op(int write, struct kiocb *iocb, char *buf, size_t count, loff_t pos)

          {

          struct async_work *async_wk;

          int result;

          //當(dāng)可以訪問(wèn)buffer時(shí)進(jìn)行復(fù)制

          if(write)

          {

          result = xxx_write (iocb->ki_filp, buf, count, &pos );

          }

          else

          {

          result = xxx_read (iocb->ki_filp, buf, count, &pos );

          }

          //如果是同步IOCB, 立即返回狀態(tài)

          if(is_sync_kiocb(iocb))

          return resutl;

          //否則,推后幾u(yù)s執(zhí)行

          async_wk = kmalloc(sizeof(*async_wk), GFP_KERNEL ));

          if(async_wk==NULL)

          return result;

          async_wk->aiocb = iocb;

          async_ wk->result = result;

          INIT_WORK(&async_wk->work, xxx_do_deferred_op, async_wk);

          schedule_delayed_work(&async_wk->work, HZ/100);

          return -EIOCBOUEUED;//控制權(quán)限返回給用戶空間

          }

          //延遲后執(zhí)行

          static void xxx_do_deferred_op(void *p)

          {

          struct async_work *async_wk = (struct async_work*)p;

          aio_complete(async_wk_iocb, async_wk->result, 0);

          kfree(async_wk);

          }

          在上述代碼中有一個(gè)async_work的結(jié)構(gòu)體定義如下:

          struct async_work

          {

          struct kiocb *iocb;//kiocb結(jié)構(gòu)體指針

          intresult;//執(zhí)行結(jié)果

          struct work_struct work; //工作結(jié)構(gòu)體

          };

          在上邊代碼中最核心的是使用aync_work結(jié)構(gòu)體將操作延遲,通過(guò)schedule_delayed_work可以調(diào)度其運(yùn)行,而aio_complete的調(diào)用用于通知內(nèi)核驅(qū)動(dòng)程序已經(jīng)完成了操作。

          最后,這一大章的內(nèi)容都講完了,一連5節(jié),小王,你好好整理整理,下次就要開(kāi)始新的內(nèi)容了。



        關(guān)鍵詞: Linux 異步I/O

        評(píng)論


        相關(guān)推薦

        技術(shù)專區(qū)

        關(guān)閉
        主站蜘蛛池模板: 会昌县| 永城市| 华亭县| 曲沃县| 通辽市| 项城市| 孙吴县| 穆棱市| 定边县| 凤台县| 莒南县| 东兴市| 南宫市| 临漳县| 西乡县| 白河县| 南江县| 安西县| 全州县| 武穴市| 密山市| 泾阳县| 成安县| 泾源县| 东乡族自治县| 正镶白旗| 根河市| 大邑县| 衢州市| 广西| 吉水县| 武功县| 孝义市| 荣昌县| 石柱| 河北区| 金山区| 邻水| 黔东| 手游| 营口市|