Linux программирование.Как отправить массив с очередью сообщений? - PullRequest
0 голосов
/ 18 декабря 2018

У меня есть writer.c и reader.c, и я пытаюсь отправить массив из writer, а затем распечатать числа в считывателе.

        //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; 
} 

Сначала я запускаю writer.c, и это мой вывод:

Отправка данных: 5

Отправка данных: 10

Отправка данных: 15

Отправка данных: 34

Отправка данных: 34

Но когда я запускаю reader.c, программа просто зависает и ничего не происходит.Любое предложение, как передать массив?

edit: Кажется, что передача только сообщения в msgsnd и msgrcv устранила проблему.

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

Ответы [ 3 ]

0 голосов
/ 18 декабря 2018

Edit: после прочтения man msgsnd немного ближе, похоже, что тип, как ожидается, будет первым полем каждого отправленного сообщения, но вы передаете каждое поле структуры индивидуально каждому msgsndвызов, поэтому тип не будет включен.Вам нужно либо отправить всю структуру сразу, либо иметь некоторый промежуточный тип структуры, если вы хотите отправить отдельные слова.

Здесь могут быть и другие проблемы.Кажется, что читатель не получает никаких сообщений вообще.Я бы начал с проверки возвращаемых значений всех системных вызовов, связанных с открытием / отправкой / получением очереди и вызовом perror () в случае неожиданного результата.

В-третьих, как упоминалось в предыдущем комментарии, вызовыmsgsnd, вероятно, не будет проходить правильно, потому что вы действительно хотите sizeof (message.a [i]).Это определенно проблема, но это не должно помешать отправке первого сообщения

Четвертое (и это не должно вызывать текущую проблему), как только вы получите свой читатель, он перезапишетсодержимое файла message.a при каждом вызове msgrcv.Вам нужно найти способ сохранить полученные данные, прежде чем снова прочитать их в сообщении.

0 голосов
/ 18 декабря 2018

man msgsnd говорит

Аргумент msgp является указателем на определяемую абонентом структуру следующего общего вида:

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

Так что

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

не так, вам нужно было полное сообщение для каждого значения, которое вы хотите, поэтому отправьте

0 голосов
/ 18 декабря 2018

Ваш код вызывает неопределенное поведение.

Поскольку вы хотите отправить целое число за целым числом, вы должны использовать sizeof(message.a[i]), что является размером одного элемента, вместо sizeof(message.a), который является размеромвесь массив a.

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

Короче говоря, это означает, что вы пропускаете мусор за массивом.

...