C的简单消息队列

让我们来看看,当你进行嵌入式开发时,你真的没有很多优秀的工具可供您使用。如果你幸运的话,你可能有一个符合C99标准的编译器和一个带有浮点硬件和DMA的微控制器。如果你不幸运,你可能有一个微控制器实际上并没有一个堆栈和一个不支持使用结构作为函数参数的编译器!
嵌入式硬件和/或开发工具链所施加的限制肯定会增加构建一个精心设计的应用程序的难度,特别是如果您的背景不在嵌入式开发中。但这并不意味着它不能完成。
在构建嵌入式应用程序时,我发现特别有用的一个工具是消息队列。队列可以用于各种事物,从应用程序的隔离组件之间传递数据到创建不可变状态持有者的外观。
c消息队列
最近我组装了一个简单的队列,可以很容易地被拉入几乎任何嵌入式应用程序。我创造性地命名为“c-message-queue”。该实现在单个头文件中定义,仅由两个宏组成。这些宏允许您创建与应用程序需求一样多的队列。队列中保存的对象类型是强类型的,并且通过强类型函数进行排队和排队。包含队列的内存在编译时静态分配,因此在运行时不需要任何弹出。
怎么运行的

我将演示一个创建队列并演示其工作原理的示例。对于此示例,队列将保存定义如下的消息:

struct message {
  char data[8];
};

队列声明
队列声明定义队列将持有什么以及它的容量。通常,声明将放在要使用队列的模块的头文件中,和/或暴露对其的访问。但是,如果没有其他模块需要与队列进行交互,则可以将其放在源文件中。
我们通过使用这样的QUEUE_DECLARATION宏来声明队列:

QUEUE_DECLARATION(my_message_queue,struct message,8);
这将创建一个包含队列本身的名为my_message_queue的结构的定义。一旦分配,队列将具有八个消息的容量。此宏还创建三个函数原型:一个用于初始化队列,另一个用于将项目排入队列和将队列排队。

void my_message_queue_init(struct my_message_queue * p_queue);
enum enqueue_result my_message_queue_enqueue(struct my_message_queue * p_queue,struct message * p_new_item);
enum dequeue_result my_message_queue_dequeue(struct my_message_queue * p_queue,struct message * p_item_out);
您可以看到,对于您创建的每个队列,您将获得特定于该队列的实用程序函数。 p_queue参数的类型与队列所具有的特定类型相匹配,而不是一个void指针,这使得不可能在队列中填充错误的项目类型,禁止强制转换。
每个入队/出队功能的返回值是一个枚举值,可以清楚地指出操作是成功还是失败。
队列定义
我们需要的第二个宏是QUEUE_DEFINITION,我们这样使用:
QUEUE_DEFINITION(my_message_queue,struct message);
这将产生上述的init,enqueue和dequeue函数的实现。传递给此宏的名称和类型必须与传递给声明的值相匹配。请注意,我们不需要再次指定大小。
排队和出队
一旦我们有了队列声明和定义,我们实际上可以创建一个队列并使用它。
要分配和初始化我们的一个队列,我们​​只需执行以下操作:
struct my_message_queue queue;
my_message_queue_init(&queue);
然后,要将一个项目放在队列中,我们可以调用这样的入队功能:
struct message msg = {
  .data = {'A','B','C','D','E','F','G','H'
};
enum enqueue_result result1 = my_message_queue_dequeue(&queue, &msg);
在我们的应用程序的其他地方,我们可以将项目从队列中拉出来:
struct message msg2;
enum dequeue_result result2 = my_message_queue_dequeue(&queue, &msg2);
if (result2 == DEQUEUE_RESULT_SUCCESS) {
   //用msg2做一些事情
}
而已。正如你所看到的,它需要很少的代码行来创建一个队列,并将项目移入和移出。
在您的应用程序中使用c-message-queue
如果您有兴趣使用此队列,您可以从GitHub获取源代码。只需克隆repo并将queue.h复制到您的项目中。存储库还包含队列实现的单元测试和一个示例项目,演示如何使用队列在应用程序的两个部分之间传递数据。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在C语言,可以使用系统提供的消息队列函数集来创建消息队列。以下是一个简单的示例程序: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #define MAX_MSG_SIZE 1024 struct message { long msg_type; char msg_data[MAX_MSG_SIZE]; }; int main(int argc, char* argv[]) { int msgid; key_t key; struct message msg; // 生成一个唯一的key if ((key = ftok(".", 'a')) == -1) { perror("ftok"); exit(EXIT_FAILURE); } // 创建消息队列 if ((msgid = msgget(key, 0666 | IPC_CREAT)) == -1) { perror("msgget"); exit(EXIT_FAILURE); } // 发送消息 msg.msg_type = 1; strcpy(msg.msg_data, "Hello, world!"); if (msgsnd(msgid, &msg, sizeof(msg), 0) == -1) { perror("msgsnd"); exit(EXIT_FAILURE); } // 接收消息 if (msgrcv(msgid, &msg, sizeof(msg), 0, 0) == -1) { perror("msgrcv"); exit(EXIT_FAILURE); } printf("Received message: %s\n", msg.msg_data); // 删除消息队列 if (msgctl(msgid, IPC_RMID, NULL) == -1) { perror("msgctl"); exit(EXIT_FAILURE); } return 0; } ``` 在上述代码,首先使用 `ftok` 函数生成一个唯一的key,然后使用 `msgget` 函数创建消息队列。发送消息使用 `msgsnd` 函数,接收消息使用 `msgrcv` 函数。最后使用 `msgctl` 函数删除消息队列。 在使用消息队列时,需要注意以下几个问题: - 消息队列的key需要保证唯一性; - 发送和接收的消息结构体需要一致; - 发送和接收时需要指定消息类型; - 消息队列的大小是有限制的,需要根据实际需求设置合适的大小; - 需要注意消息队列的并发访问问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值