kernel 異步

異步#

一旦設(shè)備就緒顽决,則主動通知應(yīng)用程序,這樣應(yīng)用程序根本就不需要查詢狀態(tài)

用戶空間處理一個設(shè)備釋放的信號的三項工作:

/* specify handler for signal */
signal(SIGIO, input_handler);

/* current process owns this fd */
fcntl(STDIN_FILENO, F_SETOWN, getpid());

/* launch the async mechanism */
flags = fcntl(STDIN_FILENO, F_GETFL);
fcntl(STDIN_FILENO, F_SETFL, flags | FASYNC);

異步通知的設(shè)備驅(qū)動模版

struct xxx_dev {
    struct cdev cdev;
    ...
    struct fasync_struct *async_queue;
};

static int xxx_fasync(int fd, struct file *filp, int mode)
{
    struct xxx_dev *dev = filp->private_data;
    /* when file has been set as async mode, add fd into async queue */
    return fasync_helper(fd, filp, mode, &dev->async_queue);
}

static ssize_t xxx_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
{
    struct xxx_dev *dev = filp->private_data;
    ...
    
    /* launch async read signal */
    if (dev->async_queue)
        kill_fasync(&dev->async_queue, SIGIO, POLL_IN);

    ...
}

static int xxx_release(struct inode *inode, struct file *filp)
{
    /* delete fd from async_queue */
    xxx_fasync(-1, filp, 0);
    ...
    return 0;
}

AIO#

異步I/O的時序:
發(fā)起I/O動作后岩四,并不等待I/O結(jié)束,

  • 要么過一段時間來查詢之前的I/O請求完成情況
  • 要么I/O請求完成了會自動調(diào)用綁定的回調(diào)函數(shù)

AIO 多種實現(xiàn)##

在用戶空間的glibc庫中實現(xiàn)###

基于線程實現(xiàn)哥攘,通過 pthread_cond_signal() 實現(xiàn)線程間同步

  1. aio_read()
  2. aio_write()
  3. aio_error() 確定請求的狀態(tài)
  4. aio_return()
  5. aio_suspend()
  6. aio_cancel()
  7. lio_listio()
  • 采用 aio_return() 不斷詢問的方式
#include <aio.h>

int fd, ret;
struct aiocb my_aiocb;

fd = open("file.txt", O_RDONLY);
if (fd < 0)
    printf("open failed\n");

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

my_aiocb.aio_buf = malloc(BUFSIZE + 1);
if (!my_aiocb.aio_buf)
    printf("malloc failed\n");

my_aiocb.aio_fildes = fd;
my_aiocb.aio_nbytes = BUFSIZE;
my_aiocb.aio_offset = 0;

ret = aio_read(&my_aiocb);
if (ret < 0)
    printf("aio_read failed\n");

while (aio_error(&my_aiocb) == EINPROGRESS)
    continue;

if ((ret = aio_return(&my_aiocb)) > 0)
    /* read success */
else
    /* read failed */
  • 采用 aio_suspend() 阻塞的方式
struct aiocb *cblist[MAX_LIST];

bzero((char *)cblist, sizeof(cblist));
cblist[0] = &my_aiocb;
...
ret = aio_read(&my_aiocb);
ret = aio_suspend(cblist, MAX_LIST, NULL);
  • 采用 lio_listio() 操作多個io control block
struct aiocb aiocb1, aiocb2;
struct aiocb *cblist[MAX_LIST];

aiocb1.aio_fildes = fd;
aiocb1.aio_buf = malloc(BUFSIZE + 1);
aiocb1.aio_nbytes = BUFSIZE;
aiocb1.aio_offset = 0;
aiocb1.aio_lio_opcode = LIO_READ;
...

bzero((char *)cblist, sizeof(cblist));
cblist[0] = &aiocb1;
cblist[1] = &aiocb2;
...

/* LIO_WAIT means block mode */
ret = lio_listio(LIO_WAIT, list, MAX_LIST, NULL);

內(nèi)核提供 libaio 的系統(tǒng)調(diào)用###

AIO的讀寫請求都用 io_submit() 下發(fā)剖煌。下發(fā)前通過 io_prep_pwrite()io_prep_pread() 生成iocb的結(jié)構(gòu)體,作為 io_submit() 的參數(shù)献丑。這個結(jié)構(gòu)體指定了讀寫類型、起始地址侠姑、長度和設(shè)備標識符等信息创橄。讀寫請求下發(fā)之后,使用 io_getevents() 函數(shù)等待I/O完成事件莽红。 io_set_callback() 設(shè)置一個AIO完成的回調(diào)函數(shù)妥畏。

file_operation 包含3個與AIO相關(guān)的成員函數(shù):

  • aio_read()
  • aio_write()
  • aio_fsync()

io_submit() 間接調(diào)用 file_operationaio_read()aio_write()

總結(jié)##

內(nèi)核包含對AIO的支持,為用戶空間提供了統(tǒng)一的異步I/O接口安吁。glibc也提供了不依賴內(nèi)核的用戶空間AIO支持醉蚁。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市鬼店,隨后出現(xiàn)的幾起案子网棍,更是在濱河造成了極大的恐慌,老刑警劉巖妇智,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件滥玷,死亡現(xiàn)場離奇詭異氏身,居然都是意外死亡,警方通過查閱死者的電腦和手機惑畴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進店門蛋欣,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人如贷,你說我怎么就攤上這事陷虎。” “怎么了杠袱?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵尚猿,是天一觀的道長。 經(jīng)常有香客問我霞掺,道長谊路,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任菩彬,我火速辦了婚禮缠劝,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘骗灶。我一直安慰自己惨恭,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布耙旦。 她就那樣靜靜地躺著脱羡,像睡著了一般。 火紅的嫁衣襯著肌膚如雪免都。 梳的紋絲不亂的頭發(fā)上锉罐,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天,我揣著相機與錄音绕娘,去河邊找鬼脓规。 笑死,一個胖子當(dāng)著我的面吹牛险领,可吹牛的內(nèi)容都是我干的侨舆。 我是一名探鬼主播,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼绢陌,長吁一口氣:“原來是場噩夢啊……” “哼挨下!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起脐湾,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤臭笆,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體耗啦,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡凿菩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了帜讲。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片衅谷。...
    茶點故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖似将,靈堂內(nèi)的尸體忽然破棺而出获黔,到底是詐尸還是另有隱情,我是刑警寧澤在验,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布玷氏,位于F島的核電站,受9級特大地震影響腋舌,放射性物質(zhì)發(fā)生泄漏盏触。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一块饺、第九天 我趴在偏房一處隱蔽的房頂上張望赞辩。 院中可真熱鬧,春花似錦授艰、人聲如沸辨嗽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽糟需。三九已至,卻和暖如春谷朝,著一層夾襖步出監(jiān)牢的瞬間洲押,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工圆凰, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留杈帐,地道東北人。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓送朱,卻偏偏與公主長得像娘荡,于是被迫代替她去往敵國和親干旁。 傳聞我的和親對象是個殘疾皇子驶沼,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,465評論 2 348

推薦閱讀更多精彩內(nèi)容