消息队列的系统限制 作者:冯老师,华清远见嵌入式学院讲师。 消息队列是System V的IPC对象的一种,用于进程间通信,会受到系统的限制,本文主要描述了三个限制。第一:议个消息的最大长度;第二:消息队列的最大容量;第三:最大消息队列数。 一、 一个消息的最大长度 示例程序如下: #include <stdio.h> #include <sys/ipc.h> #include <sys/msg.h> #include <stdlib.h> #include <errno.h> #include <string.h> #define N 8192 typedef struct { long mtype; char mtext[N]; }MSG; int main() { key_t key; int msgid; MSG buf; if ((key = ftok(".", 5)) == -1) { perror("ftok"); exit(-1); } if ((msgid = msgget(key, 0666 | IPC_CREAT)) == -1) { perror("msgget"); exit(-1); } memset(&buf, 'a', sizeof(buf)); buf.mtype = 100; if (-1 == msgsnd(msgid, &buf, N, 0)) { perror("msgsnd 1"); exit(-1); } printf("** "); return 0; } 程序执行结果如下: linux@ubuntu:~/process/fifth$ ./a.out msgsnd 1: Invalid argument 当N为8192时,可以成功执行,打印出’**”,当改成N为8193时,就出现了上面的错误,因此,消息队列中,每个消息的正文的最大长度为8192. 二、 消息队列的最大容量 示例程序如下: #include <stdio.h> #include <sys/ipc.h> #include <sys/msg.h> #include <stdlib.h> #include <errno.h> #include <string.h> #define N 8192 typedef struct { long mtype; char mtext[N]; }MSG; int main() { key_t key; int msgid; MSG buf; if ((key = ftok(".", 5)) == -1) { perror("ftok"); exit(-1); } if ((msgid = msgget(key, 0666 | IPC_CREAT)) == -1) { perror("msgget"); exit(-1); } memset(&buf, 'a', sizeof(buf)); buf.mtype = 100; if (-1 == msgsnd(msgid, &buf, N, 0)) { perror("msgsnd 1"); exit(-1); } if (-1 == msgsnd(msgid, &buf, N, 0)) { perror("msgsnd 2"); exit(-1); } if (-1 == msgsnd(msgid, &buf, 1, 0)) { perror("msgsnd 3"); exit(-1); } return 0; } 程序执行结果如下: linux@ubuntu:~/process/fifth$ ipcs -q ------------------ Message Queues -------------------- key msqid owner perms used-bytes messages 0x0501451d 131076 linux 666 16384 2 可以看出,一个消息队列中的所有消息最多占16384字节。超过这个值后,发送函数msgsnd阻塞。 三、 最大消息队列数 示例程序如下: #include <stdio.h> #include <sys/ipc.h> #include <sys/msg.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <strings.h> #define N 8192 typedef struct { long mtype; char mtext[N]; }MSG; int main() { key_t key; int msgid, i, n = 0; MSG buf; for (i = 1; ; i++) { if ((key = ftok(".", i)) == -1) { fprintf(stderr, "ftok i=%d--%s ", i, strerror(errno)); //perror("ftok"); exit(-1); } if ((msgid = msgget(key, 0666 | IPC_CREAT | IPC_EXCL)) == -1) { if (errno == EEXIST) break; //fprintf(stderr, "msgget i=%d--%s ", i, strerror(errno)); //perror("msgget"); exit(-1); } n++; } printf("n=%d msgid=%d ", n, msgid); return 0; } 程序执行结果,n为256. 该程序说明了,最多可以创建256个消息队列。