- 论坛徽章:
- 0
|
- #include <stdio.h>
- #include <errno.h>
- #include <libaio.h>
- #include <sys/eventfd.h>
- #include <sys/epoll.h>
- #include <stdlib.h>
- #include <sys/types.h>
- #include <unistd.h>
- #include <stdint.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <inttypes.h>
- #include <string.h>
- #define TEST_FILE "/home/sqg/aio_test_file"
- #define TEST_FILE_SIZE (127 * 1024)
- #define NUM_EVENTS 64
- #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);
- printf("%s\n", (char*)iocb->u.c.buf);
- }
- int main(int argc, char *argv[])
- {
- int fd_EventObj;
- int fd_File;
- io_context_t pContext;
- struct timespec tTimeSpec;
- struct io_event atIOEvent[NUM_EVENTS];
- struct custom_iocb atCustomIOCB[NUM_EVENTS];
- struct iocb *apIOCB[NUM_EVENTS];
- struct custom_iocb *apCustomIOCB;
- int i, j, r;
- void *buf;
- fd_EventObj = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
- if (fd_EventObj == -1)
- {
- perror("eventfd");
- return 2;
- }
- //O_DIRECT这个很重要
- fd_File = open(TEST_FILE, O_RDWR | O_CREAT | O_DIRECT, 0644);
- if (fd_File == -1)
- {
- perror("open");
- return 3;
- }
- pContext = 0;
- if (io_setup(NUM_EVENTS, &pContext))
- {
- perror("io_setup");
- return 4;
- }
- for (i = 0, apCustomIOCB = atCustomIOCB; i < NUM_EVENTS; ++i, ++apCustomIOCB)
- {
- if (posix_memalign(&buf, ALIGN_SIZE, RD_WR_SIZE))//可以说size是alignment倍数,alignment必须是2的幂,还是void指针的大小的倍数
- {
- perror("posix_memalign");
- return 5;
- }
- apIOCB[i] = &apCustomIOCB->iocb;
- io_prep_pread(&apCustomIOCB->iocb, fd_File, buf, RD_WR_SIZE, i * RD_WR_SIZE);
- io_set_eventfd(&apCustomIOCB->iocb, fd_EventObj);
- io_set_callback(&apCustomIOCB->iocb, aio_callback);
- apCustomIOCB->nth_request = i + 1;
- }
- if (io_submit(pContext, NUM_EVENTS, apIOCB) != NUM_EVENTS)
- {
- perror("io_submit");
- return 6;
- }
- tTimeSpec.tv_sec = 0;
- tTimeSpec.tv_nsec = 0;
- r = io_getevents(pContext, 1, NUM_EVENTS, atIOEvent, &tTimeSpec);
- if (r > 0)
- {
- for (j = 0; j < r; ++j)
- {
- //atIOEvent[j].obj是iocb的指针
- ((io_callback_t)(atIOEvent[j].data))(pContext, atIOEvent[j].obj, atIOEvent[j].res, atIOEvent[j].res2);
- }
- }
- free(buf);
- io_destroy(pContext);
- close(fd_File);
- close(fd_EventObj);
- remove(TEST_FILE);
- return 0;
- }
复制代码 上面代码是从网上抄的,下面是我的疑问
一、
下面现象,不知为啥(我printf 时加了\n怎么还会交错):
1、顺序打印了20-64
“nth_request: %d, request_type: %s, offset: %lld, length: %lu, res: %ld, res2: %ld”
2、然后再打印文件中的内容(里面交错包含了19从的nth_request: %d, request_type: %s, offset: %lld, length: %lu, res: %ld, res2: %ld)
3、printf("%s\n", (char*)iocb->u.c.buf);
二、
#define NUM_EVENTS 64
//这个宏意味着缓存大小
for (i = 0, apCustomIOCB = atCustomIOCB; i < NUM_EVENTS; ++i, ++apCustomIOCB)
{
if (posix_memalign(&buf, ALIGN_SIZE, RD_WR_SIZE))//相当于new出缓存
我试了,如果文件太大的话是读取不全的,而事实上缓存大小也不可能大于真实文件的,那么这就意味着iocb是需要反复利用,这样的代码怎么写?
三、
上面那个例子是从一个已有的文件中读取数据,那如果我现在想改下代码,从网络收取文件(非epoll,每包大小约为28K,整个文件最小为8G),应该怎么写?
io_prep_pwrite(&apCustomIOCB->iocb, fd_File, buf, RD_WR_SIZE, i * RD_WR_SIZE); |
|