qiubit
qiubit

Reputation: 4816

IPC System V message queue - sending a chunk of an array

I'm writing a program, where I need to pass a fragment of array between processes using message queue (can't use shared memory for this one...). This fragment of array may be of varying length so I'm wondering what is the best way to do that - can I specify message size during runtime? I know I can pass a structure like this through queue:

struct msg {
    long type;
    char data[N];
};

where N is determined at compile-time, and AFAIK, I can't do something like that:

struct msg {
    long type;
    char *data;
};

because contents of the pointer won't be copied, only its value...

So what is the best way to solve this value? What N should I choose in order for it to work efficiently? is sending char data[1] ok? I'm worried that if few processes will request large table, it will create a bottleneck and will not be efficient. Are my worries valid?

Upvotes: 3

Views: 755

Answers (2)

ciamej
ciamej

Reputation: 7068

Define a maximum size for the array, let's say it's 1024.

 #define MAX_SIZE 1024

Declare your struct like this:

struct msg {
    long type;
    char data[MAX_SIZE];
};

When sending send only N bytes of the content.

struct msg m;
// fill the data with N bytes
msgsnd(msqid, &m, N, msgflg);

To fill the data you can use e.g. memcpy function.

memcpy(msg.data, your_array + start_index_of_the_slice, N);

When receiving specify the maximum size i.e. MAX_SIZE. Check how many bytes have been really received by inspecting the return value of msgrcv.

struct msg m;
N = msgrcv(msqid, &m, MAX_SIZE, msgtyp, msgflg);
// use the first N data bytes

Upvotes: 2

Andrew Henle
Andrew Henle

Reputation: 1

Allocate your message structure and send the message like this:

int sendMessage( int msqid, int flags, long type, const char *data, size_t data_size )
{
    struct msgbuf *msg;
    size_t msg_size = sizeof( msg->mtype ) + data_size;
    msg = malloc( msg_size );
    msg->mtype = type;
    memcpy( msg->mtext, data, data_size );
    int rc = msgsnd( msqid, msg, msg_size, flags );
    free( msg );
    return( rc );
}

See the man page for msgsnd/msgrcv at http://man7.org/linux/man-pages/man2/msgop.2.html

Upvotes: 2

Related Questions