当前位置: 动力学知识库 > 问答 > 编程问答 >

c - Need to increase buffer for IPC message queue in OpenWRT

问题描述:

I'm just learning how to use message queues, and I am having a little difficulty with them. I am using two completely separate applications to do the testing -- one is the "sender", and the other is the "receiver".

When I run the sender, it sends 15 strings to the pipe, but then afterward fails with a "Resource temporarily unavailable" error. I just need to consume the messages on the receiver side, but why only 15 messages? I might be sending lots of messages, so I'd like to increase this to a much larger number, like 1000 or so.

I tried to set the message queue size to 32767, so I was expecting 31 at least, but apparently msg_qbytes is not related to the number of messages that can be buffered.

The sender code looks like this:

#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;

}

The receiver code looks like this:

#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;

}

网友答案:

I finally found the information: http://wiki.openwrt.org/doc/uci/system

You just have to modify /etc/config/system and add `option buffersize 65535'. Unfortunately, you can't go higher than 64k.

I made the change and it's definitely better, but not perfect. I'm going to pare down my message size to try to accommodate more messages.

网友答案:

Part of the original problem that I already solved:

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?

Ok, I failed to interpret this information correctly:

From 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.

I thought that MSG_NOERROR was optional. Guess it isn't. Problem #2 solved! Just need to increase the number of messages in the queue somehow... and then I'll probably hit another snag. :)

网友答案:

See http://publib.boulder.ibm.com/infocenter/cicsts/v3r1/index.jsp?topic=%2Fcom.ibm.cics.uc.doc%2Fcucunx%2Fmqlinux.html

This describes the file sysctl.conf on linux, other O/Ss will have other mechanisms for the same thing.

分享给朋友:
您可能感兴趣的文章:
随机阅读: