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

30 篇文章 1 订阅

我们知道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  1024

struct custom_iocb {
    struct iocb iocb;
    int nth_request;
};

void
aio_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);
}

int
main(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;
}



下面是演示结果



参考文献



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值