我只是在学习如何使用消息队列,而且我也遇到了一些困难。 我正在使用两个完全独立的应用程序来进行testing – 一个是“发件人”,另一个是“接收者”。
当我运行发件人时,它发送15个string到pipe道,但随后失败,出现“资源暂时不可用”的错误。 我只需要在接收端使用消息,但为什么只有15条消息呢? 我可能会发送很多消息,所以我想把它增加到一个更大的数字,比如1000左右。
我试图设置消息队列大小为32767,所以我至less期待31,但显然msg_qbytes
是不相关的可以缓冲的消息数量。
发件人代码如下所示:
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #include <unistd.h> #include <string.h> #define MESSAGE_SIZE 1024 typedef struct msgbuf { long mtype; char mtext[MESSAGE_SIZE]; }; int main(int argc, char *argv[]) { int msgid; int ret; struct msqid_ds msg_settings; long key; struct msgbuf msg; key = strtol(argv[1], NULL, 10); // print the message queue ID for reading via msgrcv printf( "Getting message queue with key = %ld\n", key); usleep( 1000000); msgid = msgget( (key_t)key, 0666 | IPC_CREAT); if (msgid == -1) { perror("msgget failed with error"); exit(EXIT_FAILURE); } // read in current queue settings and then set the new // queue size. ret = msgctl(msgid, IPC_STAT, &msg_settings); msg_settings.msg_qbytes = 32767; msgctl( msgid, IPC_SET, &msg_settings); while( 1) { msg.mtype = 1; // we'll always leave this as 1 memset( &(msg.mtext), 0, MESSAGE_SIZE); sprintf( msg.mtext, "hi"); printf( "Sending data: %s\n", msg.mtext); ret = msgsnd( 1, &msg, MESSAGE_SIZE, IPC_NOWAIT); usleep( 500000); if( ret == -1) { perror( "msgsnd failed\n"); } printf( "leaving...\n"); return EXIT_SUCCESS; }
接收器代码如下所示:
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #include <unistd.h> #include <string.h> #include <errno.h> #define MESSAGE_SIZE 1024 typedef struct msgbuf { long mtype; char mtext[MESSAGE_SIZE]; }; int main(int argc, char *argv[]) { long int msgtyp = 1; int ret; size_t msgsz; struct msgbuf mymsg; int msgid; msgid = strtol(argv[1], NULL, 10); printf( "Reading message queue with ID = %d\n", msgid); usleep( 1000000); while( 1) { msgsz = (size_t)MESSAGE_SIZE; ret = msgrcv( msgid, &mymsg, msgsz, msgtyp, IPC_NOWAIT); if( ret == ENOMSG) { usleep( 100000); continue; } if( ret == -1) { perror( "msgrcv failed"); } else { printf( "Read data: %s", mymsg.mtext); } usleep( 100000); } return EXIT_SUCCESS; }
我终于找到了这个信息: http : //wiki.openwrt.org/doc/uci/system
你只需要修改/ etc / config / system并添加`options buffersize 65535'。 不幸的是,你不能超过64K。
我做了改变,这绝对是更好,但并不完美。 我将削减我的邮件大小,以尝试容纳更多的消息。
我已经解决的原始问题的一部分:
On the receiver side, I always get a "Argument list too long" error. I changed my code to just use a #define so that I'm (hopefully) not making any errors when passing the size as an argument. But when I looked online for solutions to the E2BIG error, it says that the size of the message is too large. How can that be?
好的,我没有正确地解释这些信息:
从http://publib.boulder.ibm.com/infocenter/iseries/v5r3/topic/apis/ipcmsgrc.htm :
[E2BIG] Argument list too long. The size in bytes of the message is greater than msgsz and the MSG_NOERROR flag is not set in the msgflg parameter.
我以为MSG_NOERROR是可选的。 猜猜这不是。 问题#2解决了! 只需要增加队列中消息的数量……然后我可能会碰到另一个障碍。 🙂
这描述了linux上的文件sysctl.conf,其他的O / S也会有其他的机制。