前言:本篇主要总结介绍了Linux进程间通信方式之一的消息队列。包括消息队列的基本概念、相关API的介绍。
标识符与键
标识符:内核中的每一个 IPC 结构都用一个非负整数的标识符来引用。当一个 IPC 结构被创建和删除时,与该结构有关的标识符连续加 1,直到达到整型数的最大正值后回转到 0。
键:标识符是 IPC 对象的内部名,为实现多个进程在同一个 IPC 对象通信,就使用键作为该对象的外部名。每一个 IPC 对象都与一个键(key)关联。无论何时创建 IPC 结构,都要指定一个键。
键的数据类型是 key_t,一般定义在头文件 <sys/types.h> 中。键由内核转换成标识符。
ftok 生成键
ftok - convert a pathname and a project identifier to a System V IPC key
key_t ftok(const char *pathname, int proj_id);
ftok 函数只有一个功能,就是将多进程使用的同一个路径名和项目ID(0 ~ 255)转变为一个键。其中 path 必须引用一个现有的文件。产生键只使用 id 参数的低 8 位。
IPC 权限结构
Data structure used to pass permission information to IPC operations.
struct ipc_perm
{
__key_t __key; /* Key. */
__uid_t uid; /* Owner's user ID. */
__gid_t gid; /* Owner's group ID. */
__uid_t cuid; /* Creator's user ID. */
__gid_t cgid; /* Creator's group ID. */
unsigned short int mode; /* Read/write permission. */
unsigned short int __pad1;
unsigned short int __seq; /* Sequence number. */
unsigned short int __pad2;
__syscall_ulong_t __glibc_reserved1;
__syscall_ulong_t __glibc_reserved2;
};
ipc_perm 结构:每一个 IPC 结构关联了一个 ipc_perm。在创建 IPC 结构时,所有字段都赋初值。可以调用 msgctl、semctl 或 shmctl 修改 uid、gid 和 mode 字段。相当于 chown 和 chmod。
IPC 结构限制
消息队列、信号量及共享存储器这三种形式 IPC 都有内置限制。但大多限制可通过配置内核来改变,Linux OS 提供了 sysctl 命令来观察和修改内核配置参数。
可使用 ipcs -l 来显示 IPC 的限制:
coder@DESKTOP-2BH29SI:~$ sudo ipcs -l
unable to fetch message limits
------ Shared Memory Limits --------
max number of segments = 4096
max seg size (kbytes) = 18014398509481983
max total shared memory (kbytes) = 18014398509481980
min seg size (bytes) = 1
------ Semaphore Limits --------
max number of arrays = 32000
max semaphores per array = 32000
max semaphores system wide = 1024000000
max ops per semop call = 500
semaphore max value = 32767
消息队列接口
消息队列就是消息的链接表,存储在内核中,由消息队列标识符标识。
msgget:用来创建一个新的队列或是打开一个现有的队列
#include <sys/msg.h>
int msgget(key_t key, int msgflg);
msgsnd:将新消息加入到队列尾
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
msgrcv:从队列中取消息
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,
int msgflg);
msgctl:对队列执行多种操作
msgctl() performs the control operation specified by cmd on the System V message queue with identifier msqid.
int msgctl(int msqid, int cmd, struct msqid_ds *buf);