Я использую язык C с компилятором GCC в Linux. У меня есть два процесса, и я хочу передать целое число от одного процесса к другому, то есть от внешнего процесса к центральному процессу, а затем центральный процесс должен его распечатать. Но мой код не работает. Может кто подскажет как исправить? Вот мой код

Central.c

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

#define MsgKey 2345

typedef struct data_struct
{
    int  temp;
}data;

void main(void)
{
    data temp_msg;
    int msgqid;

if(msgqid=msgget(MsgKey, 0600 | IPC_CREAT)<0)
{
        printf("From Central Process: Msg queue failed");
}

msgrcv(msgqid,&temp_msg,sizeof(temp_msg),2,0);
printf("Value  = %d\n",temp_msg.temp);

printf("Central process exiting\n");
}

External.c

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

#define MsgKey 2345

typedef struct data_struct
{  
    int  temp;
}data;

void main(void)
{
    data temp_msg;
    int msgqid;

        temp_msg.temp=5;

if(msgqid=msgget(MsgKey, 0600 | IPC_CREAT)<0)
{
        printf("From External Process: Msg queue failed");
}

if(msgsnd(msgqid,&temp_msg,sizeof(temp_msg),0)<0)
{
    printf("Error");
}
printf("External process exiting\n");
}

Затем на терминале я набрал

gcc -o central central.c
gcc -o external external.c
./central &
./external

Я получил сообщение «Внешний процесс завершается», и внешний процесс завершается, в то время как центральный процесс продолжает работать в фоновом режиме.

3
Taimour 26 Апр 2014 в 10:22

2 ответа

Лучший ответ

Из документации POSIX для msgsnd:

Приложение должно гарантировать, что аргумент msgp указывает на определяемый пользователем буфер , который содержит сначала поле типа long, определяющее тип сообщения , а затем часть данных, которая содержит байты данных сообщения. . Приведенная ниже структура является примером того, как может выглядеть этот определяемый пользователем буфер:

struct mymsg {
    long   mtype;       /* Message type. */
    char   mtext[1];    /* Message text. */
}

Вы не следите за этим, поэтому ваш код не может работать. Добавьте поле long в начале вашей структуры и установите для него значение 2, поскольку это то, что ваш получатель ожидает как тип сообщения.

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

 if(msgqid=msgget(MsgKey, 0600 | IPC_CREAT)<0)

Добавьте скобки вокруг присваивания (в обоих частях кода):

 if((msgqid=msgget(MsgKey, 0600 | IPC_CREAT)) < 0)

< и другие операторы сравнения имеют более высокий приоритет, чем оператор присваивания, поэтому ваш код неверен без скобок - он присваивает результат сравнения msgqid.

И, наконец, main возвращает int , но никогда void.

1
Mat 26 Апр 2014 в 07:34

Структура, которую вы передаете msgsnd(), не соответствует требуемому формату:

struct msgbuf {
    long mtype;
    ...
};

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

Мой совет? Избегайте очередей сообщений POSIX. Если вам нужен межпроцессный обмен сообщениями, просто используйте сокеты. С ними намного проще работать и они прозрачны для сети.

1
user149341user149341 26 Апр 2014 в 07:16