gpt4 book ai didi

shared-ptr - FreeRTOS 中的共享指针和队列

转载 作者:行者123 更新时间:2023-12-04 11:34:23 25 4
gpt4 key购买 nike

围绕 FreeRTOS 队列的 C++ wapper 可以简化为如下所示:

template<typename T>
class Queue<T>
{
public:
bool push(const T& item)
{
return xQueueSendToBack(handle, &item, 0) == pdTRUE;
}

bool pop(T& target)
{
return xQueueReceive(handle, &target, 0) == pdTRUE;
}
private:
QueueHandle_t handle;
}
xQueueSendToBack 的文档状态:

The item is queued by copy, not by reference.

不幸的是,它是 字面意思 通过复制,因为它都以 memcpy 结尾,这是有道理的,因为它是一个 C API。虽然这适用于普通的旧数据,但更复杂的项目(例如以下事件消息)会带来严重的问题。

class ConnectionStatusEvent
{
public:
ConnectionStatusEvent() = default;
ConnectionStatusEvent(std::shared_ptr<ISocket> sock)
: sock(sock)
{
}

const std::shared_ptr<ISocket>& get_socket() const
{
return sock;
}

private:
const std::shared_ptr<ISocket> sock;
bool connected;
};

问题很明显是 std::shared_ptr这对 memcpy 根本不起作用因为它的复制构造函数/赋值运算符在复制到队列时不会被调用,导致在事件消息和 shared_ptr 超出范围时过早删除持有的对象。

我可以通过使用动态分配的 T 来解决这个问题-instances 并将队列更改为仅包含指向实例的指针,但我宁愿不这样做,因为这将在嵌入式系统上运行,而且我非常希望在运行时保持内存静态。

我目前的计划是更改队列以包含指向包装类中本地保存的内存区域的指针,我可以在其中实现完整的 C++ 对象复制,但由于我还需要保护该内存区域免受多线程访问,它从本质上讲,FreeRTOS 队列已经是线程安全的实现(这肯定比我自己编写的任何实现更有效),我不妨完全跳过它们。

最后,问题:

在我实现自己的队列之前,是否有任何技巧可以使用 C++ 对象实例使 FreeRTOS 队列功能,特别是 std::shared_ptr ?

最佳答案

问题是将指针放入队列后原始文件会发生什么。
复制似乎微不足道,但不是最佳的。
为了解决这个问题,我使用邮箱而不是队列:

T* data = (T*) osMailAlloc(m_mail, osWaitForever);
...
osMailPut (m_mail, data);
从哪里开始显式分配指针。只需将指针添加到邮箱即可。
并检索:
osEvent ev = osMailGet(m_mail, osWaitForever);
...
osStatus freeStatus = osMailFree(m_mail, p);
所有这些都可以巧妙地转换为 C++ 模板方法。

关于shared-ptr - FreeRTOS 中的共享指针和队列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45513057/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com