免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4582 | 回复: 0
打印 上一主题 下一主题

[C++] 复用iocb的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-10-07 18:26 |只看该作者 |倒序浏览
  1. #include <stdio.h>
  2. #include <errno.h>
  3. #include <libaio.h>
  4. #include <sys/eventfd.h>
  5. #include <sys/epoll.h>
  6. #include <stdlib.h>
  7. #include <sys/types.h>
  8. #include <unistd.h>
  9. #include <stdint.h>
  10. #include <sys/stat.h>
  11. #include <fcntl.h>
  12. #include <inttypes.h>
  13. #include <string.h>

  14. #define TEST_FILE   "/home/sqg/aio_test_file"
  15. #define TEST_FILE_SIZE  (127 * 1024)
  16. #define NUM_EVENTS  64
  17. #define ALIGN_SIZE  512
  18. #define RD_WR_SIZE  1024

  19. struct custom_iocb
  20. {
  21.     struct iocb iocb;
  22.     int nth_request;
  23. };

  24. void aio_callback(io_context_t ctx, struct iocb *iocb, long res, long res2)
  25. {
  26.     struct custom_iocb *iocbp = (struct custom_iocb *)iocb;
  27.     printf("nth_request: %d, request_type: %s, offset: %lld, length: %lu, res: %ld, res2: %ld\n",
  28.             iocbp->nth_request, (iocb->aio_lio_opcode == IO_CMD_PREAD) ? "READ" : "WRITE",
  29.             iocb->u.c.offset, iocb->u.c.nbytes, res, res2);

  30.     printf("%s\n", (char*)iocb->u.c.buf);
  31. }


  32. int main(int argc, char *argv[])
  33. {
  34.         int fd_EventObj;
  35.         int fd_File;

  36.         io_context_t pContext;
  37.         struct timespec tTimeSpec;
  38.         struct io_event atIOEvent[NUM_EVENTS];
  39.         struct custom_iocb atCustomIOCB[NUM_EVENTS];
  40.         struct iocb *apIOCB[NUM_EVENTS];
  41.         struct custom_iocb *apCustomIOCB;
  42.         int i, j, r;
  43.         void *buf;

  44.         fd_EventObj = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
  45.         if (fd_EventObj == -1)
  46.         {
  47.                 perror("eventfd");
  48.                 return 2;
  49.         }

  50.         //O_DIRECT这个很重要
  51.         fd_File = open(TEST_FILE, O_RDWR | O_CREAT | O_DIRECT, 0644);
  52.         if (fd_File == -1)
  53.         {
  54.                 perror("open");
  55.                 return 3;
  56.         }

  57.         pContext = 0;
  58.         if (io_setup(NUM_EVENTS, &pContext))
  59.         {
  60.                 perror("io_setup");
  61.                 return 4;
  62.         }


  63.         for (i = 0, apCustomIOCB = atCustomIOCB; i < NUM_EVENTS; ++i, ++apCustomIOCB)
  64.         {
  65.                 if (posix_memalign(&buf, ALIGN_SIZE, RD_WR_SIZE))//可以说size是alignment倍数,alignment必须是2的幂,还是void指针的大小的倍数
  66.                 {
  67.                         perror("posix_memalign");
  68.                         return 5;
  69.                 }
  70.                 apIOCB[i] = &apCustomIOCB->iocb;
  71.                 io_prep_pread(&apCustomIOCB->iocb, fd_File, buf, RD_WR_SIZE, i * RD_WR_SIZE);
  72.                 io_set_eventfd(&apCustomIOCB->iocb, fd_EventObj);
  73.                 io_set_callback(&apCustomIOCB->iocb, aio_callback);
  74.                 apCustomIOCB->nth_request = i + 1;
  75.         }

  76.         if (io_submit(pContext, NUM_EVENTS, apIOCB) != NUM_EVENTS)
  77.         {
  78.                 perror("io_submit");
  79.                 return 6;
  80.         }


  81.     tTimeSpec.tv_sec = 0;
  82.     tTimeSpec.tv_nsec = 0;
  83.     r = io_getevents(pContext, 1, NUM_EVENTS, atIOEvent, &tTimeSpec);
  84.     if (r > 0)
  85.     {
  86.         for (j = 0; j < r; ++j)
  87.         {
  88.             //atIOEvent[j].obj是iocb的指针
  89.             ((io_callback_t)(atIOEvent[j].data))(pContext, atIOEvent[j].obj, atIOEvent[j].res, atIOEvent[j].res2);
  90.         }
  91.     }



  92.         free(buf);
  93.         io_destroy(pContext);
  94.         close(fd_File);
  95.         close(fd_EventObj);
  96.         remove(TEST_FILE);

  97.         return 0;
  98. }
复制代码
上面代码是从网上抄的,下面是我的疑问
一、
下面现象,不知为啥(我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);
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP