首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >静态消息队列

静态消息队列
EN

Stack Overflow用户
提问于 2015-12-09 10:41:58
回答 1查看 268关注 0票数 1

我在一个微控制器上有不同的逻辑单元,它们必须能够相互通信。这些单位我称之为组件。

每个组件都有一个在编译时定义了固定大小的消息队列。我不希望任何动态分配的内存。

每个组件都有一个消息插槽数组。一个插槽可以有三种不同的状态:

  • 未用
  • 预留
  • 可加工性

如果组件A想首先向组件B发送消息,则需要保留一个消息插槽。它可以直接写入这个时隙的消息数据。最后,它需要将槽设置为可处理的。现在,组件B可以处理数据并再次将插槽设置为未使用的。秩序将是重要的,但就目前而言,我忽视它。

代码语言:javascript
复制
class CommunicationManager {
public:
    CommunicationManager(ComponentManager& componentManager);
    MessageSlot * getMessageSlot(int componentId);

private:
    ComponentManager& componentManager;
};

class Component {
public:
    Component(CommunicationManager& communicationManager);
    virtual void process() = 0;
    MessageSlot * getMessageSlot();

    virtual ~Component();

protected:
    MessageQueue<5> messageQueue;
    CommunicationManager& communicationManager;
};

消息传递是用这些类完成的。

代码语言:javascript
复制
template <int size>
class MessageQueue {
public:
    MessageSlot* reserveMessageSlot();
    MessageSlot * getProcessableMessageSlot();
    bool processableMessageSlotAvailable();

private:
    MessageSlot messageSlots[size];
};

class MessageSlot {
public:
    void reserve();
    bool isReserved();
    bool isProcessable();
    void setProcessable();
    void reset();

    Message * getMessage();
private:
    Message message;

    bool reserved;
    bool processable;
};

class Message {
public:
    int sender;
    int receiver;

    int length;
    char data[8];
};

通过这种方式,目前的通信方式:

代码语言:javascript
复制
// sender part
MessageSlot * slot = communicationManger.getMessageSlot(SPI_COMPONENT_ID);
// fill message with data
slot->setProcessable();

// receiver part
MessageSlot * slot = messageQueue.getProcessableMessageSlot();
if (slot != 0) {
    // process message data
    // if processing was successful reset message slot
    slot->reset();
}

正如您现在所看到的,用户必须使用时隙类。你有什么想法来隐藏这个实现吗?我不想复制任何数据。

我的目标是这样的:

代码语言:javascript
复制
// sender
Message * msg = communicationManager.reserveMessage(SPI_COMPONENT_ID);
// fill message with data

如何发出信号表示可以处理此消息?我不想要消息数据中的标志。我可以说,必须在调用之后填充数据,因为没有真正的并行处理。但这样我就不高兴了。

代码语言:javascript
复制
// receiver part
Message * msg = messageQueue.getProcessableMessage();
if (msg != 0) {
    // process message data
    // if processing was successful reset message slot
    messageQueue.messageProcessed();
}
EN

回答 1

Stack Overflow用户

发布于 2015-12-09 11:14:01

我想在这里找雷伊。当资源超出作用域时,使用清除资源的对象。作为部分例子:

发送

代码语言:javascript
复制
class Request {
  friend class CommunicationManager;
  Request(MessageSlot* slot);
  MessageSlot* slot_;

 public:
    Request(Request&&);
    ~Request();
    // Functions to add data into the message
};
Request::Request(Request&& other) : slot_(other.slot_) { other.slot_ = nullptr; }
Request::Request(MessageSlot* slot) : slot_(slot) {}
Request::~Request() {
  if (slot_)
    slot_->setProcessable();
}

接收

代码语言:javascript
复制
class Message {
  friend class MessageQueue;
  Message(MessageSlot* slot);
  MessageSlot* slot_;

 public:
    Message(Message&&);
    ~Message();
    explicit operator bool();
    // Functions to read data the message
};
Message::Message(Message&& other) : slot_(other.slot_) { other.slot_ = nullptr; }
Message::Message(MessageSlot* slot) : slot_(slot) {}
Message::~Message() {
  if (slot_)
    slot_->reset();
}
Message::operator bool() {
  return nullptr != slot_;
}

使用:

代码语言:javascript
复制
{  // Any scope (function, condition, forced scope)
  Request req = communicationManager.reserveMessage(SPI_COMPONENT_ID);
  // Fill with data
}


{  // Any scope (function, condition, forced scope)
  Message msg = messageQueue.getProcessableMessage();
  if (msg) {
    // process message data
  }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34176742

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档