如何在标准 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!
$