如何在标准 C 中实现消息队列
How to implement a message queue in standard C
我有一个项目(使用 C 代码的微控制器 STM32),我需要从串行端口接收消息(例如字符串),我需要将消息放入队列中,稍后我将在其中读取字符串。
有人能告诉我在哪里可以找到有关如何使用标准创建字符串(或字节数组)的消息队列(如 FIFO)的示例C 以及如何管理队列?感谢您的任何形式的支持。
C 语言没有内置队列(这是一种排除电池的语言),您需要自己构建。如果你只需要一个 FIFO 来在你的中断例程中推送东西,然后在你的主循环中弹出它们(顺便说一句,这是一个很好的设计),检查 A Simple Message Queue for C 这是否适合你。
“有关如何使用标准 C 创建字符串(或字节数组)的消息队列(如 FIFO)以及如何管理队列的示例”
“在带有标准 C 的微控制器中,您应该管理缓冲区、创建队列、对元素进行入队和出队”
下面给出的例子应该符合要求。
如有必要,使用的库函数可以很容易地替换为 platform-specific 版本或标准 C 数组操作。
队列的内存分配也可以作为静态变量而不是堆栈变量来完成。如果需要,甚至可以使用 malloc
。
消息类型可以轻松扩展。队列和数据大小定义为常量。
@leonardo 很好地提示了如何构建处理过程,即在中断例程中对消息进行排队,并在 main 中将它们出队。我想需要使用某种信号量,这样操作队列的函数的执行就不会混淆。
中讨论了对此的一些想法
/*
Portable array-based cyclic FIFO queue.
*/
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#define MESSAGE_SIZE 64
#define QUEUE_SIZE 3
typedef struct {
char data[MESSAGE_SIZE];
} MESSAGE;
typedef struct {
MESSAGE messages[QUEUE_SIZE];
int begin;
int end;
int current_load;
} QUEUE;
void init_queue(QUEUE *queue) {
queue->begin = 0;
queue->end = 0;
queue->current_load = 0;
memset(&queue->messages[0], 0, QUEUE_SIZE * sizeof(MESSAGE_SIZE));
}
bool enque(QUEUE *queue, MESSAGE *message) {
if (queue->current_load < QUEUE_SIZE) {
if (queue->end == QUEUE_SIZE) {
queue->end = 0;
}
queue->messages[queue->end] = *message;
queue->end++;
queue->current_load++;
return true;
} else {
return false;
}
}
bool deque(QUEUE *queue, MESSAGE *message) {
if (queue->current_load > 0) {
*message = queue->messages[queue->begin];
memset(&queue->messages[queue->begin], 0, sizeof(MESSAGE));
queue->begin = (queue->begin + 1) % QUEUE_SIZE;
queue->current_load--;
return true;
} else {
return false;
}
}
int main(int argc, char** argv) {
QUEUE queue;
init_queue(&queue);
MESSAGE message1 = {"This is"};
MESSAGE message2 = {"a simple"};
MESSAGE message3 = {"queue!"};
enque(&queue, &message1);
enque(&queue, &message2);
enque(&queue, &message3);
MESSAGE rec;
while (deque(&queue, &rec)) {
printf("%s\n", &rec.data[0]);
}
}
编译和运行:
$ gcc -Wall queue.c
$ ./a.out
This is
a simple
queue!
$
我有一个项目(使用 C 代码的微控制器 STM32),我需要从串行端口接收消息(例如字符串),我需要将消息放入队列中,稍后我将在其中读取字符串。
有人能告诉我在哪里可以找到有关如何使用标准创建字符串(或字节数组)的消息队列(如 FIFO)的示例C 以及如何管理队列?感谢您的任何形式的支持。
C 语言没有内置队列(这是一种排除电池的语言),您需要自己构建。如果你只需要一个 FIFO 来在你的中断例程中推送东西,然后在你的主循环中弹出它们(顺便说一句,这是一个很好的设计),检查 A Simple Message Queue for C 这是否适合你。
“有关如何使用标准 C 创建字符串(或字节数组)的消息队列(如 FIFO)以及如何管理队列的示例”
“在带有标准 C 的微控制器中,您应该管理缓冲区、创建队列、对元素进行入队和出队”
下面给出的例子应该符合要求。
如有必要,使用的库函数可以很容易地替换为 platform-specific 版本或标准 C 数组操作。
队列的内存分配也可以作为静态变量而不是堆栈变量来完成。如果需要,甚至可以使用 malloc
。
消息类型可以轻松扩展。队列和数据大小定义为常量。
@leonardo 很好地提示了如何构建处理过程,即在中断例程中对消息进行排队,并在 main 中将它们出队。我想需要使用某种信号量,这样操作队列的函数的执行就不会混淆。
/*
Portable array-based cyclic FIFO queue.
*/
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#define MESSAGE_SIZE 64
#define QUEUE_SIZE 3
typedef struct {
char data[MESSAGE_SIZE];
} MESSAGE;
typedef struct {
MESSAGE messages[QUEUE_SIZE];
int begin;
int end;
int current_load;
} QUEUE;
void init_queue(QUEUE *queue) {
queue->begin = 0;
queue->end = 0;
queue->current_load = 0;
memset(&queue->messages[0], 0, QUEUE_SIZE * sizeof(MESSAGE_SIZE));
}
bool enque(QUEUE *queue, MESSAGE *message) {
if (queue->current_load < QUEUE_SIZE) {
if (queue->end == QUEUE_SIZE) {
queue->end = 0;
}
queue->messages[queue->end] = *message;
queue->end++;
queue->current_load++;
return true;
} else {
return false;
}
}
bool deque(QUEUE *queue, MESSAGE *message) {
if (queue->current_load > 0) {
*message = queue->messages[queue->begin];
memset(&queue->messages[queue->begin], 0, sizeof(MESSAGE));
queue->begin = (queue->begin + 1) % QUEUE_SIZE;
queue->current_load--;
return true;
} else {
return false;
}
}
int main(int argc, char** argv) {
QUEUE queue;
init_queue(&queue);
MESSAGE message1 = {"This is"};
MESSAGE message2 = {"a simple"};
MESSAGE message3 = {"queue!"};
enque(&queue, &message1);
enque(&queue, &message2);
enque(&queue, &message3);
MESSAGE rec;
while (deque(&queue, &rec)) {
printf("%s\n", &rec.data[0]);
}
}
编译和运行:
$ gcc -Wall queue.c
$ ./a.out
This is
a simple
queue!
$