rt-thread icon indicating copy to clipboard operation
rt-thread copied to clipboard

消息队列接口设计不合理,rt_mq_recv应该传出消息的实际大小

Open FragrantRye opened this issue 3 years ago • 6 comments

向消息队列发送消息时调用:

rt_mq_send(&mq, data, data_len);

可发送指定长度的消息。 而在接受时调用:

char buff[MAX_SIZE];
rt_mq_recv(&mq, buff, MAX_SIZE, timeout);

无法取到所发送数据的实际长度,必须自己设计数据结构在data中存放长度,造成编程上的不便以及不必要的开销。 建议给recv增加一个可传出实际消息长度的版本,类似这样:

rt_err_t rt_mq_recv_with_size(rt_mq_t    mq,
                    void      *buffer,
                    rt_size_t  size,
                    rt_size_t  *real_size,
                    rt_int32_t timeout)

FragrantRye avatar Mar 29 '22 03:03 FragrantRye

消息队列里的消息体要求是固定等长的 不是你这样用的 发送的消息体长度是 data_len 接收的时候也必须是 data_len 消息队列消息池的大小是消息体字节大小乘以最大容纳消息个数。更多描述可以看 https://club.rt-thread.org/ask/article/3186.html 这里的相关小节

thewon86 avatar Mar 30 '22 00:03 thewon86

见官方API参考手册中"详细描述"一节,其中明确提到: 消息队列可以应用于发送不定长消息的场合 只要所发送消息小于创建消息队列时指定的最大msg_size即可。 而且实际中也是有很多需要传输变长消息的需求的,如果只能传定长消息那就只能用固定消息头+动态分配payload内存的形式,这样带来的性能开销特别大。

FragrantRye avatar Mar 30 '22 02:03 FragrantRye

描述有问题,上面论坛链接里也有提到几种传递不定长消息的方式。可以看看哪种适合你。 目前没有不定长消息机制

thewon86 avatar Mar 30 '22 05:03 thewon86

感觉这个可以在5.0里改进一下,确实用的很难受,接受发送API里message size那个参数填了根本没啥意义

mysterywolf avatar Apr 08 '22 05:04 mysterywolf

mq本身是用于快速的,小批量的消息传输,并不是还针对每个消息还设计成变长的。如果是变长方式,内部设计都会变化,一些特性要支持起来也会带来更大的代价。

在接收消息时,可以获得这个消息的长度,这个也许是可以,例如每条消息变成:

struct msg{
  len_type_t len;
  uint8_t data[0];
};
  • 这里的len_type_t也会引入歧途,uint16_t,那么后续的data肯定也就不是32位对齐,这个时候在对齐面前又会有一定的尴尬;
  • 如果len_type_t是uint32_t,那么前面的空间肯定也就浪费掉了的。

BernardXiong avatar Apr 16 '22 08:04 BernardXiong

确切的说,应该是消息的内存池是肯定是定长的,消息长度不能多于一个消息的内存池大小,但是小于是可以的。因此需要返回实际消息的大小。

mysterywolf avatar Apr 16 '22 17:04 mysterywolf

https://github.com/RT-Thread/rt-thread/pull/7709 此PR已经解决

mysterywolf avatar Jun 26 '23 04:06 mysterywolf