新聞中心

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

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

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

          “小王,接著昨天的來(lái),你知道嗎?在異步IO中,什么可以用來(lái)做為AIO的通知呢?”我用渴求的眼神望著她.

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

          "啊?那我咋知道,你說(shuō)的我能記住就不錯(cuò)了,讓我發(fā)明創(chuàng)造,我可是不會(huì)."小王委屈道。

          “笨死了,我前邊花了那么多的時(shí)間來(lái)講信號(hào)之類(lèi)的東西,聯(lián)想一下信號(hào)作為的信號(hào),也想的出來(lái)啊,告訴你,我當(dāng)年用腳肢頭都能想到,可你..真讓我失望”我嘆氣到,“算了,也不怪你了,咱們開(kāi)始繼續(xù)學(xué)習(xí)吧“。

          先上代碼:使用信號(hào)作為AIO異步IO通知機(jī)制

          void setup_io(..)

          {

          int fd;

          struct sigaction sig_act;

          struct aiocb my_aiocb;

          ...

          //設(shè)置信號(hào)處理函數(shù)

          sigemptyset(&sig_act.sa_mask);

          sig_act.sa_flags = SA_SIGINFO;

          sig_act.sa_sigaction = aio_completion_handler;

          //設(shè)置AIO請(qǐng)求

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

          my_aiocb.aio_flags = fd;

          my_aiocb.aio_buf = malloc(BUF_SIZE + 1);

          my_aiocb.aio_nbytes = BUF_SIZE;

          my_aiocb.offset = next_offset;

          //連接AIO請(qǐng)求和信號(hào)處理函數(shù)

          my_aiocb.aio_sigevent.sigev_notify = SIGEV_SIGNVAL;

          my_aiocb.aio_sigevent.sigev_signo = SIGIO;

          my_aiocb.aic_sigevent.sigev_value.sival_ptr = &my_aiocb;

          //將信號(hào)和處理函數(shù)綁定

          ret = sigaction(SIGION, &sig_act, NULL);

          ...

          ret = aio_read(&my_aiocb);

          }

          //信號(hào)處理函數(shù)

          void aio_completion_handler(int signo, siginfo_t *info, void *context)

          {

          struct aiocb *req;

          //確定是我們需要的信號(hào)

          if(info->si_signo == SIGIO)

          {

          req = (struct aiocb *)info->si_value.sival_ptr; //獲得aiocb;

          //請(qǐng)求的操作是否完成

          if(aio_error(req) ==0 )

          {

          ret = aio_return(req);

          }

          }

          return ;

          }

          從上邊可以看到,使用AIO的應(yīng)用程序同樣需要定義信號(hào)處理函數(shù),在指定的信號(hào)被產(chǎn)生時(shí)會(huì)觸發(fā)調(diào)用這個(gè)處理程序。

          “那么是不是就只能使用信號(hào)這種方式呢,我記得以前沒(méi)一個(gè)知識(shí)點(diǎn)你都給我講了好多方法,這個(gè)歌也不例外吧”小王說(shuō)。

          “嗯,真聰明,就喜歡聰明的女生”聽(tīng)到小王也懂得開(kāi)動(dòng)腦子了,我也要表示表示不是。

          再上代碼:使用回調(diào)函數(shù)最為AIO的通知

          void setup_io(..)

          {

          ...//同上

          //連接AIO請(qǐng)求和線(xiàn)程回調(diào)函數(shù)

          my_aiocb.aio_sigevent.sigev_notify = SIGEV_THREAD;

          my_aiocb.aio_sigevent.notify_function = aio_completion_handler;

          //設(shè)置回調(diào)函數(shù)

          my_aiocb.aio_sigevent.notify_attributes = NULL;

          my_aiocb.aio_sigevent.sigev_value.sival_ptr = &my_aiocb;

          ...

          ret = aio_read(&my_aiocb);

          }

          //信號(hào)處理函數(shù)

          void aio_completion_handler(int signo, siginfo_t *info, void *context)

          {

          struct aiocb *req;

          req = (struct aiocb *)sigval.sival_ptr; //獲得aiocb;

          //請(qǐng)求的操作是否完成

          if(aio_error(req) ==0 )

          {

          ret = aio_return(req);

          }

          return ;

          }

          上述程序在創(chuàng)建aiocb請(qǐng)求之后,使用SIGEV_THREAD請(qǐng)求了一個(gè)線(xiàn)程回調(diào)函數(shù)作為通知方法。在回調(diào)函數(shù)中。通過(guò)(struct aiocb *)info->si_value.sival_ptr可以獲得對(duì)應(yīng)的aiocb指針,使用AIO函數(shù)可驗(yàn)證請(qǐng)求是否已經(jīng)完成。

          “不過(guò),小王,對(duì)不起哈,沒(méi)想到一說(shuō)就收不住了,這節(jié)也只是講了有關(guān)的應(yīng)用,下節(jié)咱們開(kāi)始講講AIO與驅(qū)動(dòng)設(shè)備,回歸驅(qū)動(dòng)主題”。



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

        評(píng)論


        相關(guān)推薦

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

        關(guān)閉
        主站蜘蛛池模板: 庆云县| 芜湖市| 奎屯市| 山东省| 绍兴市| 吴旗县| 洪雅县| 五寨县| 汶上县| 钦州市| 灵丘县| 北碚区| 安康市| 错那县| 祥云县| 唐河县| 漯河市| 嵊泗县| 克东县| 黑河市| 迭部县| 左贡县| 丹江口市| 孙吴县| 察隅县| 沂源县| 阿拉善右旗| 静安区| 甘肃省| 繁峙县| 东兰县| 镶黄旗| 荣昌县| 河北省| 玉环县| 连云港市| 宜良县| 刚察县| 彭水| 四子王旗| 株洲县|