maibox
mailbox传递一堆数据时需要传递的是“指针变量“的”地址”,即指针的指针 (类型定义 **p),messageQueen 确实直接的变量值赋值。所以在rt-thread应用文档里做了比较详细的说明。对比着看才看得明白了一些,说明c语言不使用复杂环境还是不敢说完全掌握啊。身边Linux玩的好的人c语言功底一般很好,那是c语言描述的最复杂的事物了吧。
struct msg
{
rt_uint8_t *data_ptr;
rt_uint32_t data_size;
};
这是应用手册中推荐了一种用邮箱传递大量数据的方法,额外的构造一个结构体类型。
struct msg* msg_ptr;
msg_ptr = (struct msg*)rt_malloc(sizeof(struct msg));
msg_ptr->data_ptr = ...; /* 指向相应的数据块地址*/
msg_ptr->data_size = len; /* 数据块的长度*/
/* 发送这个消息指针给mb 邮箱*/
rt_mb_send(mb, (rt_uint32_t)msg_ptr);
把需要传递的结构体变量的地址发送到邮箱。
struct msg* msg_ptr;
if (rt_mb_recv(mb, (rt_uint32_t*)&msg_ptr) == RT_EOK)
{
/* 在接收线程处理完毕后, 需要释放相应的内存块*/
rt_free(msg_ptr);
}
而在接收线程中,因为收取过来的是指针,而msg_ptr 是一个新分配出来的内存块,所以在接收线程处理完毕后,需要释放相应的内存块
这个地方需要对这个结构体指针变量取地址操作
if (rt_mb_recv(mb, (rt_uint32_t*)&msg_ptr) == RT_EOK)
让结构体指针变量存储邮箱中的结构体地址,因为对指针变量理解不深刻,这个地方总感觉有点怪怪的。所谓指针变量其实也是个变量而已,指针变量也需要在内存中占用4个字节,所以指针变量也有地址。当传递参数时也需要对指针变量进行取地址,才能改变指针变量中存储的值。和需要改变数据变量的原理是一样的。
messageQueen
手册中说到但消息队列也只有4个字节可以使用时,可以参考mailBox
struct msg
{
rt_uint8_t *data_ptr; /* 数据块首地址*/
rt_uint32_t data_size; /* 数据块大小*/
};
void send_op(void *data, rt_size_t length)
{
struct msg msg_ptr;
msg_ptr.data_ptr = data; /* 指向相应的数据块地址*/
msg_ptr.data_size = length; /* 数据块的长度*/
/* 发送这个消息指针给mq 消息队列*/
rt_mq_send(mq, (void*)&msg_ptr, sizeof(struct msg));
}
void message_handler()
{
struct msg msg_ptr; /* 用于放置消息的局部变量*/
/* 从消息队列中接收消息到msg_ptr 中*/
if (rt_mq_recv(mq, (void*)&msg_ptr, sizeof(struct msg)) == RT_EOK)
{
/* 成功接收到消息, 进行相应的数据处理*/
}
}
rt_mq_recv函数中使用的是传结构地址,所以在 rt_mq_recv函数中使用的是逐个复制结构体中的变量值,如下
/**
* This function will receive a message from message queue object, if there is
* no message in message queue object, the thread shall wait for a specified
* time.
*
* @param mq the message queue object
* @param buffer the received message will be saved in
* @param size the size of buffer
* @param timeout the waiting time
*
* @return the error code
*/
rt_err_t rt_mq_recv(rt_mq_t mq,
void *buffer,
rt_size_t size,
rt_int32_t timeout)
/* copy message */
rt_memcpy(buffer, msg + 1, size > mq->msg_size ? mq->msg_size : size);
估计采用邮箱传递是不是快点。
原来都是裸机写程序多,把复杂点的程序自己合理的使用c语言面向对象封装下,使用全局变量传递下函数也没有大问题。现在os下写程序是个趋势了,活到老学到老啊。还好是硬件编程技术发展没有web编程技术快,其实还是稍微轻松点。
想想为什么线程间的传递参数搞得好像这么复杂,好像就是为了避开全局变量在线程间传递变量进行通信。做到线程的独立性,线程间的解耦。一个线程操作异常,不会影响其他线程,容错性加强,鲁棒性也提高了吧。没有良好书写习惯,全局变量乱放的程序看得会让人吐血。自从互联网连接的代码资源越来越多,看程序,移植程序的时间会比写程序的时间多。原来的老工程师都是拿起要求就写,现在就不一样了,没有时间的积累,自己写的程序还没有别人的好用,美观,简洁。