mmap的 Bus error问题及解决

前言

新交易系统中,通过mmap来实现持仓和订单的本地持久化,之前未用过mmap,在本次实现中遇到了一些问题,仅记录Bus error问题;

实现

基本逻辑

OM或者PM在启动时,先通过本地的持久化文件来恢复订单或者持仓:

  • 如果是当日的第一次的正常启动,那么是没有持久化文件的,这个时候,PM需要从别的地方来获取初始化的持仓(当天还没有开始交易,没有订单,OM不需要做处理);
  • 如果不是当天的第一次正常启动,那么是有持久化文件的,OM或者PM就需要从本地的持久化文件来获取订单和持仓,完成初始化;

问题

持久化是通过mmap映射本地文件来实现的,遇到了Bus error的问题,什么原因呢?
是因为在当天的第一次正常启动时,是没有持久化文件的(对每个策略而言,持久化文件以天为单位来建立并记录的),这时需要先建立持久化文件,然后通过mmap进行映射后再写入记录信息;问题就出在了建立新文件后mmap映射修改,具体原因可以参考:
使用mmap遇到总线错误bus error
发生错误的原因是因为mmap不能去扩展一个内容为空的新文件,因为大小为0,所有本没有与之对应的合法的物理页,不能扩展。

解决

解决方案有2个:
一个就是上面的链接里的方案: 只需要在新创建的空文件中先写入一些数据即可
另外一个是通过ftruncate对新建立的文件进行扩展后再映射修改

int fd = open("/workspace/delete/data.txt", O_RDWR | O_CREAT, 777);
  if(!fd) {
    printf("!fd\n");
    return -1;
  }
  //方案1: write(fd,"1",1);
  ftruncate(fd, 4096*10);   // 方案2

  void* m_mmap =
    mmap(NULL, 4096*10, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
  if(!m_mmap){
    printf("!m_mmap\n");
    return -1;
  }
  printf("come here\n");

  Position cur_pos;
  char buf[1024];
  for (int i = 1; i < 10; i++) {    
    cur_pos.symbol = i*2 + 15;
    cur_pos.pos_long = i*3 + 15;
    cur_pos.pos_short = i*4 + 15;
    cur_pos.long_pending = i*5 + 15;
    cur_pos.short_pending = i*6 + 15;
    printf("%d: %lld,%d,%d,%d,%d\n", i-1, cur_pos.symbol, cur_pos.pos_long, cur_pos.pos_short, cur_pos.long_pending, cur_pos.short_pending);
    memcpy( (void*)((char*)m_mmap + sizeof(Position)*(i-1)), &cur_pos, sizeof(cur_pos));
    //memcpy( (buf + sizeof(Position)*(i-1)), &cur_pos, sizeof(cur_pos));
  }
  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lqw198421

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值