简体   繁体   中英

Linux programming. How to send array with message queue?

I have writer.c and reader.c and I am trying to send array from writer and then print the numbers in the reader.

        //writer.c

    #include <stdio.h> 
    #include <sys/ipc.h> 
    #include <sys/msg.h> 

    // structure for message queue 
    struct mesg_buffer { 
        int mesg_type; 
        int a[5];

    } message; 

    int main() 
    { 
    message.a [0] = 5;
    message.a [1] = 10;
    message.a [2] = 15;
    message.a [3] = 34;
    message.a [4] = 34;

        key_t key; 
        int msgid; 

        // ftok to generate unique key 
        key = ftok(".", 65); 

        // msgget creates a message queue 
        // and returns identifier 
        msgid = msgget(key, 0666 | IPC_CREAT); 
        message.mesg_type = 1; 

 // msgsnd to send message 
    for(int i=0;i<5;i++)
    msgsnd(msgid, (int *) &message.a[i], sizeof(message.a[i]), 0);



        // display the message 
    for(int i=0;i<5;i++)
        printf("Data send is : %d \n", message.a[i]); 

        return 0; 
    } 

reader.c

 // C Program for Message Queue (Reader Process) 
#include <stdio.h> 
#include <sys/ipc.h> 
#include <sys/msg.h> 

// structure for message queue 
struct mesg_buffer { 
    int mesg_type; 
    int a[5];
} message; 

int main() 
{ 
    key_t key; 
    int msgid; 

    // ftok to generate unique key 
    key = ftok(".", 65); 

    // msgget creates a message queue 
    // and returns identifier 
    msgid = msgget(key, 0666 | IPC_CREAT); 

    // msgrcv to receive message
    for(int i=0; i<5; i++)
   msgrcv(msgid, &message, sizeof(message.a[i]), 1, 0); 

    for(int i=0; i<5; i++)
    printf("Data Received is : %d \n",  
                    message.a[i]); 

    // to destroy the message queue 
    msgctl(msgid, IPC_RMID, NULL); 

    return 0; 
} 

I run firstly the writer.c and that's my output:

Data send is : 5

Data send is : 10

Data send is : 15

Data send is :34

Data send is : 34

But when I run the reader.c the program just stucks and nothing happens. Any suggestion how to pass the array?

edit: It seems that passing only the message in msgsnd and msgrcv fixed the problem.

for(int i=0;i<5;i++)
    msgsnd(msgid, &message, sizeof(message), 0); 

Your code invokes undefined behavior.

Since you want to send integer-by-integer, you should use sizeof(message.a[i]) , what is size of one element, instead of sizeof(message.a) , which is size of the whole array a .

msgsnd(msgid, (int *) &message.a[i], sizeof(message.a), 0);
                                            ^^^^^^^^^

In short it means you are passing some garbage behind the array.

Edit: After reading man msgsnd a bit close, it looks like the type is expected to be the first field of each message sent, but you're passing each field of the structure individually to each msgsnd call, so the type won't be included. You either need to send the entire structure at once or have some intermediate struct type if you want to send individual words.

There could be a few other issues here too. It seems like the reader is not receiving any messages at all. I would start by checking the return values of all the system calls related to queue opening/sending/receiving and calling perror() in case of an unexpected result.

Third, as the previous comment mentions, the calls to msgsnd are likely not going to go through correctly because you really want sizeof(message.a[i]). This is defintely an issue, but it shouldn't stop the first message from being sent

Fourth (and this one shouldn't be causing the current issue), once you get your reader receiving, it's going to overwrite the contents of message.a on each call to msgrcv. You need to find a way to preserve the received data before reading it into message again.

man msgsnd says

The msgp argument is a pointer to caller-defined structure of the following general form:

struct msgbuf {
    long mtype;       /* message type, must be > 0 */
    char mtext[1];    /* message data */
};

So

msgsnd(msgid, (int *) &message.a[i], sizeof(message.a[i]), 0);

is wrong, you had to have a complete message for each value you want so send

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM