libaio中的异步IO要比glibc更接近系统内核,
它对内核的调用是通过嵌入式汇编实现的,实际是对系统内核的封装,里面没什么东西
关于内核嵌入式汇编的调用,看下面这两个
http://jianlee.ylinux.org/Computer/Kernel/system_call_list.html
http://zhoulifa.bokee.com/2821589.html
关于O_DIRECT选项的,看这个
http://www.ukuug.org/events/linux2001/papers/html/AArcangeli-o_direct.html
Libaio这个版本里面,没什么值得分析的代码
#if defined(__i386__) /* little endian, 32 bits */
#define PADDED(x, y) x; unsigned y
#define PADDEDptr(x, y) x; unsigned y
#define PADDEDul(x, y) unsigned long x; unsigned y
struct io_iocb_poll {
PADDED(int events, __pad1);
}; /* result code is the set of result flags or -'ve errno */
struct io_iocb_sockaddr {
struct sockaddr *addr;
int len;
}; /* result code is the length of the sockaddr, or -'ve errno */
存放数据的结构体
struct io_iocb_common {
PADDEDptr(void *buf, __pad1);
PADDEDul(nbytes, __pad2);
long long offset;
long long __pad3;
unsigned flags;
unsigned resfd;
}; /* result code is the amount read or -'ve errno */
struct io_iocb_vector {
const struct iovec *vec;
int nr;
long long offset;
}; /* result code is the amount read or -'ve errno */
struct iocb {
PADDEDptr(void *data, __pad1); /* Return in the io completion event */
PADDED(unsigned key, __pad2); /* For use in identifying io requests */
short aio_lio_opcode;
short aio_reqprio;
int aio_fildes; //文件句柄
union {
struct io_iocb_common c;
struct io_iocb_vector v;
struct io_iocb_poll poll;
struct io_iocb_sockaddr saddr;
} u;
};
struct io_event {
PADDEDptr(void *data, __pad1);
PADDEDptr(struct iocb *obj, __pad2);
PADDEDul(res, __pad3);
PADDEDul(res2, __pad4);
};
这两个函数就是填充一下结构体,别的什么也没用
static inline void io_prep_pread(struct iocb *iocb, int fd, void *buf, size_t count, long long offset)
{
memset(iocb, 0, sizeof(*iocb));
iocb->aio_fildes = fd;
iocb->aio_lio_opcode = IO_CMD_PREAD;
iocb->aio_reqprio = 0;
iocb->u.c.buf = buf;
iocb->u.c.nbytes = count;
iocb->u.c.offset = offset;
}
static inline void io_prep_pwrite(struct iocb *iocb, int fd, void *buf, size_t count, long long offset)
{
memset(iocb, 0, sizeof(*iocb));
iocb->aio_fildes = fd;
iocb->aio_lio_opcode = IO_CMD_PWRITE;
iocb->aio_reqprio = 0;
iocb->u.c.buf = buf;
iocb->u.c.nbytes = count;
iocb->u.c.offset = offset;
}
io_setup, io_submit, io_getevents, io_cancel, 全是通过嵌入式汇编调的底层操作系统的实现,在这些函数内部没其它的操作,对这些函数的分析需要分析操作系统内核代码
libaio内部没有用线程模拟同时对多文件的读写,只不过是操作系统的简单封装,这个和glibc有很大的不同,这际是可有可无,用户完全可以直接调用操作系统内核实现,不需libaio包