静态消息队列
Static message queue
我在微控制器上有不同的逻辑单元,它们必须能够相互通信。这些单元我称之为组件。
每个组件都有一个在编译时定义的固定大小的消息队列。我不想要任何动态分配的内存。
每个组件都有一组消息槽。一个插槽可以有三种不同的状态:
- 未使用
- 保留
- 可处理
如果组件A想要首先向组件B发送消息,则需要预留消息时隙。它可以直接写入该插槽的消息数据。最后,它需要将插槽设置为可处理。现在,组件B可以处理数据并再次将插槽设置为未使用。订单很重要,但目前我忽略了它
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;
};
消息传递是通过这些类完成的。
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];
};
目前通信是这样工作的:
// 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();
}
正如您现在所看到的,用户必须使用slot类。你有什么隐藏实施的想法吗?我不想复制任何数据。
我的目标是这样的:
// sender
Message * msg = communicationManager.reserveMessage(SPI_COMPONENT_ID);
// fill message with data
如何发出可以处理此消息的信号?我不想在消息数据中使用标志。我可以说,在这个调用之后必须填充数据,因为没有真正的并行处理。但我不会对这种方式感到高兴。
// receiver part
Message * msg = messageQueue.getProcessableMessage();
if (msg != 0) {
// process message data
// if processing was successful reset message slot
messageQueue.messageProcessed();
}
我会在这里选择RAII。当资源超出范围时,您可以使用清除资源的对象。作为部分示例:
发送:
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();
}
接收:
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_;
}
用法:
{ // 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
}
}
相关文章:
- boost::进程间消息队列引发错误
- 避免使用 boost::进程间::消息队列创建文件
- 提升消息队列 跨两个进程未接收
- 可以将Boost消息队列文件重定向到用户指定的位置
- 使用加速进程间创建消息队列 - 内存访问冲突
- 如何检查提升消息队列是否存在
- Win32 消息队列在使用 OpenGL 渲染时被淹没
- 在尝试使用boost时断言.跨很多过程中的互动消息队列
- GetMessage/PeekMessage - 删除消息队列中的所有消息
- IPC Unix 消息队列线程安全吗?
- NS2:AODV路由消息停留在队列中
- 在.c文件接收函数中使用Linux中的MSGGET创建消息队列未实现错误
- boost消息队列线程安全和进程安全吗?
- 如何处理多个源队列消息类型
- 为什么我的无锁消息队列段错误:(?
- 在控制台应用程序中处理空的windows消息队列
- 关于在这种情况下消息队列与共享内存的适用性或适用性
- boost::进程间消息队列创建时的竞争条件
- 从内存转储中查找线程消息队列中的消息
- win32消息泵,do dispatchMessage()处理整个消息队列或仅仅是顶部消息