0Pricing
C Academy · 课时

消息队列

结构化消息传递

消息队列 是 CoddyKit 上的免费 C Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 C Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 C Academy 课程共包含 4 节课。

结构化消息传递

消息队列允许进程交换独立的消息,而不是原始字节流。内核会保留消息边界,因此每次发送恰好对应一次接收。

消息与流

管道传递的是字节流,边界会变得模糊。消息队列传递的是完整的单元:

  • 每次 send 发送一条消息
  • 每次 receive 接收一条消息
  • 消息可以设置优先级

POSIX 与 System V 队列

有两套 API:

  • POSIX:mq_open、mq_send、mq_receive,名称以斜杠开头
  • System V:msgget、msgsnd、msgrcv,基于键值并支持带类型的消息

POSIX 是更简洁、现代的选择。

打开队列

mq_open 会创建或打开一个命名队列,并返回描述符。您可以传入最大消息数量和消息大小等属性。

#include <mqueue.h>
#include <fcntl.h>

mqd_t open_queue(const char *name) {
    return mq_open(name, O_CREAT | O_RDWR, 0644, NULL);
    /* name like "/myqueue"; NULL uses default attributes */
}

队列属性

struct mq_attr 定义了 mq_maxmsg(容量)和 mq_msgsize(每条消息的最大字节数)。接收方的缓冲区至少必须达到 mq_msgsize 大小。

#include <mqueue.h>

void set_attr(struct mq_attr *a) {
    a->mq_flags = 0;
    a->mq_maxmsg = 10;     /* up to 10 queued messages */
    a->mq_msgsize = 256;   /* each at most 256 bytes */
    a->mq_curmsgs = 0;
}

发送消息

mq_send 会将带有优先级的消息放入队列。优先级较高的消息会先送达。

#include <mqueue.h>
#include <string.h>

int post(mqd_t q, const char *text) {
    return mq_send(q, text, strlen(text) + 1, 5); /* priority 5 */
}

接收消息

mq_receive 会返回优先级最高的消息。缓冲区至少必须达到 mq_msgsize 大小,否则调用会因 EMSGSIZE 而失败。

#include <mqueue.h>
#include <stdio.h>

void get(mqd_t q, size_t msgsize) {
    char buf[256];
    unsigned prio;
    ssize_t n = mq_receive(q, buf, msgsize, &prio);
    if (n >= 0) printf("got (prio %u): %s\n", prio, buf);
}

优先级决定传递顺序

与 FIFO 管道不同,消息队列会优先按优先级传递消息;优先级相同时,再按到达顺序传递。这样,紧急消息就可以插队。

阻塞与非阻塞

默认情况下,队列已满时 mq_send 会阻塞,队列为空时 mq_receive 会阻塞。使用 O_NONBLOCK 打开队列后,它们会返回 EAGAIN,而不是等待。

定时操作

mq_timedsend 和 mq_timedreceive 接受一个绝对截止时间。如果操作无法在规定时间内完成,就会因 ETIMEDOUT 而失败,从而避免无限等待。

清理资源

使用 mq_close 关闭描述符,并使用 mq_unlink 从系统中删除命名队列,这样所有使用者完成操作后,队列就不会继续存在。

#include <mqueue.h>

void cleanup(mqd_t q, const char *name) {
    mq_close(q);
    mq_unlink(name); /* remove the named queue */
}

快速检查

测试您对消息队列的理解。

回顾

您学会了 POSIX 消息队列。

  • 交换独立的消息,而不是原始字节
  • mq_open、mq_send、mq_receive
  • 先按优先级传递,再按到达顺序传递
  • 可选择非阻塞和定时变体;使用 mq_close 和 mq_unlink 清理资源

常见问题解答

「消息队列」课时是免费的吗?

是的 — 「消息队列」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 C Academy 课程的其余内容,请升级到 CoddyKit PRO。 C Academy 课程共包含 4 节课。

「消息队列」这节课中我会学到什么?

结构化消息传递 你通过在浏览器中直接运行的动手代码来练习 C Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 C Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 C Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。

「消息队列」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 C Academy 课中编写并运行代码吗?

能。每节 C Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 管道
  2. 共享内存
  3. 消息队列
  4. 信号
← 返回 C Academy