菜鸟科技网

Linux mq命令具体如何使用?

mqMessage Queue(消息队列)的缩写,在 Linux 中,消息队列是一种进程间通信机制,它允许一个或多个发送者将消息发送给一个或多个接收者,与管道和信号量等其他 IPC 机制相比,消息队列具有一些显著优点:

Linux mq命令具体如何使用?-图1
(图片来源网络,侵删)
  • 生命周期随内核:消息队列独立于创建它的进程,即使进程退出,队列中的消息仍然存在,直到被显式删除或系统重启。
  • 类型化消息:可以发送和接收带有特定类型的消息,接收者可以根据类型有选择地接收消息。
  • 容量更大:相比于管道(通常几 KB),消息队列可以存储更多的消息。
  • 更丰富的功能:支持消息优先级、非阻塞操作等。

在 Linux 中,与消息队列交互主要有两种方式:

  1. 使用命令行工具:主要用于查看、管理和删除已有的消息队列。
  2. 使用 C 语言库函数:在应用程序中创建、发送和接收消息。

下面我们重点介绍命令行工具。


查看 ipcs 命令

ipcs 是一个强大的命令,用于查看系统上现有的 IPC 资源,包括消息队列共享内存信号量

基本用法

要查看所有消息队列,使用 ipcs -q

Linux mq命令具体如何使用?-图2
(图片来源网络,侵删)
# 查看所有消息队列的摘要信息
ipcs -q
# 或者使用长选项
ipcs --queues

输出解读

执行 ipcs -q 后,你会看到类似下面的输出:

------ Message Queues --------
key        msqid      owner      perms      used-bytes   messages
0x00000000 65536      root       644        0            0
0x12345678 196609     myuser     660        128          2

每一列的含义如下:

  • key: 消息队列的键值,这是在创建队列时指定的,用于唯一标识一个队列,如果键为 0x00000000,通常表示这是一个私有队列(通过 msgget 使用 IPC_PRIVATE 标志创建)。
  • msqid: 消息队列的 ID,这是系统内部使用的唯一标识符,当你想要在程序中操作这个队列时,需要使用这个 ID。
  • owner: 拥有该队列的用户。
  • perms: 队列的权限,格式为八进制(644,表示所有者有读写权限,组用户和其他用户有读权限)。
  • used-bytes: 队列中当前所有消息占用的总字节数。
  • messages: 队列中当前消息的总数量。

常用选项

  • -i msqid: 显示指定 ID 的消息队列的详细信息。

    # 查看 ID 为 196609 的消息队列详情
    ipcs -i 196609

    输出会包含该队列的限制(如最大字节数、最大消息数)和当前状态。

  • -p: 显示创建和最后操作该队列的进程 ID (PID)。

    ipcs -q -p
  • -c: 显示创建该队列的命令。

    ipcs -q -c
  • --human: 以人类可读的格式显示大小(KB, MB)。

    ipcs -q --human

删除 ipcrm 命令

ipcrm 用于删除一个或多个指定的 IPC 资源,包括消息队列、共享内存和信号量。

警告:使用 ipcrm 会立即删除指定的 IPC 资源,并且队列中所有未读的消息都会被永久销毁,请谨慎使用,特别是在生产环境中。

删除消息队列

有两种方式可以删除消息队列:

通过队列 ID (msqid) 删除

这是最常用的方式,你可以先使用 ipcs -q 找到要删除的队列的 msqid,然后用它来删除。

# 删除 ID 为 196609 的消息队列
ipcrm -q 196609

通过队列键 (key) 删除

如果你知道创建队列时使用的键,也可以直接通过键来删除。

# 删除键为 0x12345678 的消息队列
ipcrm -Q 0x12345678

删除其他 IPC 资源

ipcrm 也可以删除共享内存 (-m) 和信号量 (-s)。

# 删除 ID 为 shmid 的共享内存段
ipcrm -m shmid
# 删除 ID 为 semid 的信号量集
ipcrm -s semid

强制删除所有消息队列(不推荐)

如果你想清理掉系统上所有由当前用户创建的消息队列,可以结合 ipcsxargs 来实现。

# 警告:此命令会删除当前用户所有的消息队列!
ipcs -q | awk 'NR > 2 {print $2}' | xargs -n 1 ipcrm -q

命令解释:

  1. ipcs -q: 列出所有消息队列。
  2. awk 'NR > 2 {print $2}': awk 用于处理文本。NR > 2 表示跳过前两行(标题行),{print $2} 表示打印每一行的第二列,也就是 msqid
  3. xargs -n 1 ipcrm -q: xargsawk 输出的 msqid 列表作为参数,逐个(-n 1)传递给 ipcrm -q 命令执行。

sendmsgrecvmsg 命令

sendmsgrecvmsg 是 C 语言库函数,而不是直接的 shell 命令,Linux 提供了两个简单的命令行工具 sendmsgrecvmsg(通常包含在 util-linux 包中),它们是这些 C 函数的薄封装,用于在命令行上快速测试和交互消息队列。

使用 sendmsg 发送消息

# 基本语法
sendmsg [options] msqid "message_text"
# 常用选项
# -t <type>: 指定消息的类型(一个正整数)
# -c: 以文本模式发送
# -b: 以二进制模式发送

示例: 假设我们有一个 msqid196609 的消息队列,我们想发送一条类型为 1 的消息。

# 发送一条类型为 1 的文本消息 "Hello from the command line"
sendmsg -t 1 196609 "Hello from the command line"

使用 recvmsg 接收消息

# 基本语法
recvmsg [options] msqid
# 常用选项
# -t <type>: 指定要接收的消息类型
#     -t 0: 接收队列中第一个消息(FIFO)
#     -t > 0: 接收指定类型的消息
#     -t < 0: 接收类型小于或等于 abs(type) 的最低类型消息
# -n: 以非阻塞模式接收,如果队列为空,立即返回而不是等待。
# -o: 从队列中移除接收到的消息(默认行为)。
# -l: 只列出消息而不从队列中移除。

示例: 从 msqid196609 的队列中接收消息。

# 阻塞式接收类型为 1 的消息(如果没有,会一直等待)
recvmsg -t 1 196609
# 非阻塞式接收类型为 1 的消息(如果没有,会立即报错并退出)
recvmsg -t 1 -n 196609
# 只查看队列中最早的一条消息,但不删除它
recvmsg -l 196609

总结与工作流

  1. 创建:消息队列通常由 C 程序通过 msgget() 函数创建,键值可以通过 ftok() 生成或手动指定。
  2. 查看:使用 ipcs -q 查看系统上所有消息队列的状态,找到你关心的队列的 msqidkey
  3. 交互:使用 sendmsgrecvmsg 命令向队列发送或从中读取消息,用于调试或简单的测试。
  4. 删除:当不再需要消息队列时,使用 ipcrm -q <msqid>ipcrm -Q <key> 将其从系统中移除,释放资源。

掌握这几个命令,你就可以在 Linux 系统上有效地管理和调试基于消息队列的应用程序了。

分享:
扫描分享到社交APP
上一篇
下一篇