在Ubuntu 16.04.1 LTS上测试Linux AIO功能实录

来源:互联网 发布:算法初步ppt 编辑:程序博客网 时间:2024/06/11 09:42

我们知道nginx中有libaio这项功能,为了研究AIO的一些常用接口用法,在网上找到一个例子,异步IO读取本地文件,亲自实践了一把,记录如下:


安装依赖库

在Ubuntu 16.04上需要事先安装
apt-cache search aio

sudo apt-get install libaio1 libaio-dev

如果是CentOS,需要执行下面的命令先查询再安装
yum search libaio
yum -y install libaio libaio-devel

下面时源码例子

//description: 测试Linux的原生AIO功能演示//refer: http://blog.chinaunix.net/uid-16979052-id-3840266.html//dependence://  sudo apt-get install libaio1 libaio-dev (Ubuntu 16.04.1)//  yum -y install libaio libaio-devel (CentOS 6.x)//compile: gcc -g epoll_aio.c -o epoll_aio -laio//run: ./epoll_aio//#define _GNU_SOURCE#define __STDC_FORMAT_MACROS#include <stdio.h>#include <stdlib.h>#include <stdint.h>#include <unistd.h>#include <errno.h>#include <libaio.h>#include <sys/eventfd.h>#include <sys/epoll.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <inttypes.h>//为简单起见,需要事先从网上下载一个文件,并存放在当前目录下面,//并设置它的大小,这里选择”http://news.sohu.com/“,存为aio_sample.html#define TEST_FILE   "aio_sample.html"#define TEST_FILE_SIZE  239576#define NUM_EVENTS  128#define ALIGN_SIZE  512#define RD_WR_SIZE  1024struct custom_iocb {    struct iocb iocb;    int nth_request;};voidaio_callback(io_context_t ctx, struct iocb *iocb, long res, long res2){    struct custom_iocb *iocbp = (struct custom_iocb *) iocb;    printf("nth_request: %d, request_type: %s, offset: %lld, length: %lu, res: %ld, res2: %ld\n", iocbp->nth_request, (iocb->aio_lio_opcode == IO_CMD_PREAD) ? "READ" : "WRITE", iocb->u.c.offset, iocb->u.c.nbytes, res, res2);}intmain(int argc, char *argv[]){    int efd, fd, epfd;    io_context_t ctx;    struct timespec tms;    struct io_event events[NUM_EVENTS];    struct custom_iocb iocbs[NUM_EVENTS];    struct iocb *iocbps[NUM_EVENTS];    struct custom_iocb *iocbp;    struct epoll_event epevent;    int i, j, r;    void *buf;    efd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);    if (efd == -1)    {perror("eventfd");return 2;    }    //打开本地测试文件    fd = open(TEST_FILE, O_RDWR | O_CREAT | O_DIRECT, 0644);    if (fd == -1)    {perror("open");return 3;    }    //截断到指定大小    ftruncate(fd, TEST_FILE_SIZE);    ctx = 0;    if (io_setup(8192, &ctx))    {perror("io_setup");return 4;    }    if (posix_memalign(&buf, ALIGN_SIZE, RD_WR_SIZE))    {perror("posix_memalign");return 5;    }    printf("buf: %p\n", buf);    for (i = 0, iocbp = iocbs; i < NUM_EVENTS; ++i, ++iocbp)    {iocbps[i] = &iocbp->iocb;io_prep_pread(&iocbp->iocb, fd, buf, RD_WR_SIZE, i * RD_WR_SIZE);io_set_eventfd(&iocbp->iocb, efd);io_set_callback(&iocbp->iocb, aio_callback);iocbp->nth_request = i + 1;    }    if (io_submit(ctx, NUM_EVENTS, iocbps) != NUM_EVENTS)    {perror("io_submit");return 6;    }    epfd = epoll_create(1);    if (epfd == -1)    {perror("epoll_create");return 7;    }    epevent.events = EPOLLIN | EPOLLET;    epevent.data.ptr = NULL;    if (epoll_ctl(epfd, EPOLL_CTL_ADD, efd, &epevent))    {perror("epoll_ctl");return 8;    }    i = 0;    while (i < NUM_EVENTS)    {uint64_t finished_aio;if (epoll_wait(epfd, &epevent, 1, -1) != 1){    perror("epoll_wait");    return 9;}if (read(efd, &finished_aio, sizeof (finished_aio)) !=    sizeof (finished_aio)){    perror("read");    return 10;}printf("finished io number: %" PRIu64 "\n", finished_aio);while (finished_aio > 0){    tms.tv_sec = 0;    tms.tv_nsec = 0;    r = io_getevents(ctx, 1, NUM_EVENTS, events, &tms);    if (r > 0)    {for (j = 0; j < r; ++j){    ((io_callback_t) (events[j].data)) (ctx, events[j].obj,events[j].res,events[j].res2);}i += r;finished_aio -= r;    }}    }    close(epfd);    free(buf);    io_destroy(ctx);    close(fd);    close(efd);    remove(TEST_FILE);    return 0;}



下面是演示结果



参考文献

http://blog.chinaunix.net/uid-16979052-id-3840266.html


原创粉丝点击