linux IPC-消息队列
几乎所有的 Linux 发行版本都包含 ipcs 命令,该命令可以提供当前加载到系统上的
IPC资源信息。通过ipcs可以确定系统的当前IPC限制,还可以检查系统当前使用的上述
三类IPC资源的状态。例如,假若应用程序启动失败,可以检查系统上的IPC使用情况来
判断是否已超出了某个IPC限制。为了确定系统的IPC资源状态,可以在root用户权限下
执行带有-u选项的ipcs命令。
#ipcs-u
------SharedMemoryStatus--------
segmentsallocated32
pagesallocated2361
pagesresident253
pagesswapped982
Swapperformance:0attempts0successes
------SemaphoreStatus--------
usedarrays=128
allocatedsemaphores=256
------ Messages: Status --------allocated queues = 0
usedheaders=0
usedspace=0bytes
对于“ipcs-u”命令所显示的IPC资源,如果要确定其限制,可以使用“ipcs-l”命令:
#ipcs-l
------SharedMemoryLimits--------
maxnumberofsegments=4096
maxsegsize(kbytes)=32768
maxtotalsharedmemory(kbytes)=8388608
minsegsize(bytes)=1
------SemaphoreLimits--------
maxnumberofarrays=128
maxsemaphoresperarray=250
maxsemaphoressystemwide=32000
maxopspersemopcall=32
semaphoremaxvalue=32767
------Messages:Limits--------
maxqueuessystemwide=16
maxsizeofmessage(bytes)=8192
defaultmaxsizeofqueue(bytes)=16384
上述输出表明,该系统已经到达信号量数组(或信号量集合)的数目上限。这个限制可
以通过增加内核参数semmni的取值来解决,该参数定义了系统能够拥有的信号量集合的
总数。Linux 可以动态调整大多数内核IPC 参数值的大小,也可以静态地修改消息队列为进程提供了一种异步传递消息的方法。在使用 msgget()建立了一条消息队
列之后,发送进程和接收进程就可以通过这条消息队列交换消息。发送进程将消息发送到
指定的消息队列,而接收者试图从指定的消息队列中获取消息。如果该队列中没有消息的
话,则接收者根据自己是否要等待的意愿而阻塞或返回某个标志。
表13-2简要描述了在当前Linux2.4/2.6内核实现中提供的3个消息队列参数。
表13-2与消息队列相关的内核参数
名称描述默认值最大值
msgmni最大消息队列数162GB
msgmax最大消息长度(字节数)81922GB
msgmnb消息队列中的最大字节数163842GB
注意,第4列中给出的最大值取决于数据类型。上述3个内核参数都是int类型,因
此在32位Intel机器上,硬性上限是2GB。
Linux还定义了其他当前未用的消息队列相关参数。
以下各节具体分析与消息队列相关的参数13.5.1 msgmni
msgmni定义了系统范围内的消息队列上限。与信号量一样,消息队列也拥有一个相关
的标识符。在系统初始化阶段里,内核创建一个指向消息队列标识符结构的指针数组。该
数组的项数由msgmni确定。对于每个消息队列,Linux内核为标识符分配44B,为消息队
列数据结构分配96B。为了获得更多的消息队列资源,可以动态增加msgmni取值。和信
号量一样,消息队列标识符的最大数目也受限于IPCMNI。msgmni的默认上限为16B,这
可能不足以保证一些大型数据库应用平滑地运行。如果在系统上要运行数据库应用的话,
推荐默认上限值是128B。
13.5.2msgmax
msgmax限制进程可以发送的消息长度。该参数由Msgsnd()函数加以应用。如果待发
送消息的长度超过该值,则返回一个错误。该参数可以在运行时调整13.5.3 msgmnb
msgmnb确定一个消息队列的容量。该参数的取值存储在消息队列标识符结构的某个
域中,用于确定是否存在着对新消息进行排队的空间。msgmnb值可以动态修改,默认为
16384。修改其取值会影响到所有新的消息队列的容量。用户可以通过Msgctl()系统调用来
增加现有消息队列的容量修改消息队列的参数
1.永久修改root用户下修改/etc/sysctl.conf 文件。
2.临时修改
root用户下sysctl-wkernel.msgmnb=1048576