<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > Linux內核開發(fā)之異步通知與異步I/O(五)

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

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

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

          本文引用地址:http://www.ex-cimer.com/article/201612/342072.htm

            在內核中,每個IO請求都對應一個kiocb結構體,其ki_filp成員指向對應的file指針,通過is_sync_kiocb可以判斷某Kiocb時候為同步IO請求,如果非真,表示是異步IO請求。

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

            在字符設備驅動程序中,file_operations包含了3個和AIO相關的函數(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ù)不同,它直接傳遞值,而后者傳遞的是指針。這兩個函數(shù)本身也不一定完成讀寫操作,它只是發(fā)起,初始化讀寫操作。

            下面來看看實際的代碼部分:

            //異步讀

            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);

            }

            //異步寫

            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;

            //當可以訪問buffer時進行復制

            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;

            //否則,推后幾us執(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;//控制權限返回給用戶空間

            }

            //延遲后執(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);

            }

            在上述代碼中有一個async_work的結構體定義如下:

            struct async_work

            {

            struct kiocb *iocb;//kiocb結構體指針

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

            struct work_struct work; //工作結構體

            };

            在上邊代碼中最核心的是使用aync_work結構體將操作延遲,通過schedule_delayed_work可以調度其運行,而aio_complete的調用用于通知內核驅動程序已經(jīng)完成了操作。

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



          關鍵詞: Linux 異步I/O

          評論


          相關推薦

          技術專區(qū)

          關閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();