segment.h

这篇博客详细介绍了如何在C++中实现共享内存段的管理,包括OpenOrCreate函数用于创建共享内存,CreateBlocksField函数创建block数组,CreateBlockBuffers分配并初始化每个块的缓冲区,以及AcquireBlockToWrite和AcquireBlockToRead函数分别用于获取可写和可读的块。整个过程涉及到进程间通信的关键操作,如原子操作和锁机制。
摘要由CSDN通过智能技术生成
namespace movex {
namespace cyber {
namespace transport {

class Segment;
using SegmentPtr = std::shared_ptr<Segment>;

struct WritableBlock {
  uint32_t index = 0;
  Block* block = nullptr;
  uint8_t* buf = nullptr;
};
using ReadableBlock = WritableBlock;

class Segment {
 public:
  explicit Segment(uint64_t channel_id);
  virtual ~Segment() {}

  bool AcquireBlockToWrite(std::size_t msg_size, WritableBlock* writable_block);
  void ReleaseWrittenBlock(const WritableBlock& writable_block);

  bool AcquireBlockToRead(ReadableBlock* readable_block);
  void ReleaseReadBlock(const ReadableBlock& readable_block);

  void CheckSegmentBlock();

 protected:
  virtual bool Destroy();
  virtual void Reset() = 0;
  virtual bool Remove() = 0;
  virtual bool OpenOnly() = 0;
  virtual bool OpenOrCreate() = 0;

  bool init_;
  ShmConf conf_;
  uint64_t channel_id_;

  State* state_;
  Block* blocks_;
  void* managed_shm_;
  std::mutex block_buf_lock_;
  std::unordered_map<uint32_t, uint8_t*> block_buf_addrs_;

 private:
  bool Remap();
  bool Recreate(const uint64_t& msg_size);
  uint32_t GetNextWritableBlockIndex();
};

}  // namespace transport
}  // namespace cyber
}  // namespace movex
namespace movex {
namespace cyber {
namespace transport {
namespace {
constexpr double kBlockLockTime = 10.0;
}

Segment::Segment(uint64_t channel_id)
    : init_(false),
      conf_(),
      channel_id_(channel_id),
      state_(nullptr),
      blocks_(nullptr),
      managed_shm_(nullptr),
      block_buf_lock_(),
      block_buf_addrs_() {}

bool Segment::AcquireBlockToWrite(std::size_t msg_size,
                                  WritableBlock* writable_block) {
  RETURN_VAL_IF_NULL(writable_block, false);
   /*创建共享内存以及块的概念  具体见下面分析*/
    if (!init_ && !OpenOrCreate()) {
    AERROR << "create shm failed, can't write now.";
    return false;
  }

  /* 判断是否需要重新映射*/
  bool result = true;
  if (state_->need_remap()) {
    result = Remap();
  }

    /*消息过大的话,立即销毁重新开始OpenOrCreate(),大小重新分配*/
  if (msg_size > conf_.ceiling_msg_size()) {
    AINFO << "msg_size: " << msg_size
          << " larger than current shm_buffer_size: "
          << conf_.ceiling_msg_size() << " , need recreate.";
    result = Recreate(msg_size);
  }

  if (!result) {
    AERROR << "segment update failed.";
    return false;
  }
  
  uint32_t index = GetNextWritableBlockIndex();
  if (UINT32_MAX == index) {
    return false;
  }
  writable_block->index = index;
  writable_block->block = &blocks_[index];
  writable_block->buf = block_buf_addrs_[index];
  return true;
}

void Segment::ReleaseWrittenBlock(const WritableBlock& writable_block) {
  auto index = writable_block.index;
  if (index >= conf_.block_num()) {
    return;
  }
  blocks_[index].ReleaseWriteLock();
}

bool Segment::AcquireBlockToRead(ReadableBlock* readable_block) {
  RETURN_VAL_IF_NULL(readable_block, false);
  if (!init_ && !OpenOnly()) {
    AERROR << "failed to open shared mem
  • 20
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

lobmo

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

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

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

打赏作者

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

抵扣说明:

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

余额充值