2015-09-19 3 views
2

У меня возникли проблемы с настройкой очереди сообщений System V и правильной работой в Linux. Идея состоит в том, чтобы получить центральный узел для извлечения данных из нескольких других узлов. Проблема в том, что центральный узел заканчивается там, ожидая, пока другие узлы будут отправлять сообщения. Я просмотрел значения для почтовых ящиков, и они одинаковы для всех процессов. И.Е. 0 для центрального почтового ящика, 32769 для другого процесса 1, ect. Я понятия не имею, почему он, похоже, терпит неудачу. Я попытался изменить параметр приоритета в msgrcv на 0, чтобы принять все входящие сообщения и возникла одна и та же проблема. Любая помощь будет очень полезна. (. Извините за отсутствие комментариев)Неисправность очереди сообщений системы V

Вот код для центрального узла:

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

struct{ 
    long priority; 
    int temperature; 
    int pid; 
    int stable; 
} msgp; 

const int mainMailID = 8484; 

using namespace std; 

int main(int argc, char* argv[]){ 

//declare needed variables 
int centralMailID; 
int externalMailID[4]; 
int tempdata; 
int externalTempature[4]; 
int externalTemperatureLast[4]; 

//set initial values for msgp 
msgp.priority = 2; 
msgp.temperature = atoi(argv[1]); 
msgp.pid = 0; 
msgp.stable = 0; 

//create the central mailbox 
centralMailID = msgget(mainMailID, 0600 | IPC_CREAT); 

if(centralMailID == -1){ 
    cout << "Message Queue Creation Failed" << endl; 

} 
else{ 
    cout << "Message Queue Created" << endl; 
} 

//create the external mailboxes 
for(int i = 0; i < 4 ; i++){ 

    externalMailID[i] = msgget(mainMailID + i+1, 0600 | IPC_CREAT); 

    if(externalMailID[i] == -1){ 
     cout << "Message Queue " << i << " Creation Failed" << endl; 
    } 
    else{ 
     cout << "Message Queue " << i << " Created" << endl; 
    } 
} 

printf("%i", externalMailID[0]); 

while(msgp.stable == 0){ 

    int centralTemperature = msgp.temperature; 

    //get the tempatures from the external sensors. 
    for(int i = 0; i<4; i++){ 

     tempdata = msgrcv(externalMailID[i], &msgp, sizeof(msgp)-sizeof(long), 2, 0); 

     cout << "Recived data from sensor " << msgp.pid << endl; 

     externalTempature[i] = msgp.temperature; 
    } 

    if(externalTempature[0] == externalTempature[1] == externalTempature[2] == externalTempature[3] == centralTemperature){ 

     msgp.stable = 1; 
     continue; //could also use break 
    } 

    int sum = 0; 

    for(int i = 0; i<4; i++){ 

     sum = sum + externalTempature[i]; 
    } 

    centralTemperature = ((2 * centralTemperature) + sum)/6; 
    msgp.temperature = centralTemperature; 

    for(int i = 0; i<4; i++){ 

     tempdata = msgsnd(externalMailID[i], &msgp, sizeof(msgp)-sizeof(long), 0); 

     printf("Sent data to external mailbox %i", i); 
    } 
} 
printf("Process ended"); 
return 0; 
} 

Вот код для других узлов:

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

struct{ 
    long priority; 
    int temperature; 
    int pid; 
    int stable; 
} msgp; 

const int mainMailID = 8484; 

using namespace std; 

int main(int argc, char* argv[]){ 


int centralMailID = msgget(mainMailID, 0600 | IPC_CREAT); 
int pid = atoi(argv[2]); 
int externalMailID = msgget(mainMailID + pid, 0600 | IPC_CREAT); 
int externalTemperature = atoi(argv[1]); 
int tempdata; 

cout << externalMailID << endl; 

msgp.priority = 2; 

msgp.pid = pid; 
msgp.stable = 0; 

while(msgp.stable == 0){ 

    msgp.temperature = externalTemperature; 

    tempdata = msgsnd(centralMailID, &msgp, sizeof(msgp)-sizeof(long), 0); 

    tempdata = msgrcv(externalMailID, &msgp, sizeof(msgp)-sizeof(long), 2, 0); 

    externalTemperature = ((externalTemperature * 3) + (msgp.temperature * 2))/5; 

    if(msgp.stable == 1){ 

     continue; 
    } 
} 

printf("Child Process Ended"); 
return 0; 
} 

ответ

0

Вы используете системы V api, что, вероятно, не то, что вы хотите. Смотрите здесь для более подробной информации:

http://mij.oltrelinux.com/devel/unixprg/#ipc__posix_msgqs


msgget, msgctl, msgsnd, команды msgrcv являются частью V апи старше, системы, и в то время как семантика похожи, не являются очереди POSIX. Несколько быстрых поисков google для учебных заданий/примеров системы V, скорее всего, помогут решить вашу проблему.

Если вы действительно хотите использовать posix queues, переключитесь и найдите документацию по файлам mq_open, mq_close, mq_unlink, mq_send, mq_receive, mq_getattr, mq_setattr api.

+0

Повторите попытку с указанной ссылки. Ссылка только ответы не полезны для SO, поскольку ссылки имеют тенденцию гнить. –

+0

Почему вы предполагаете, что API системы V - это не то, что хочет OP? Эти API все еще преподаются во многих областях. – syntagma

+0

он явно заявляет, что он использует posix queues, но его код показывает системные очереди V. если его обучают очередным постам, он использует неправильную апи. если его учат системе V очереди, он задает неправильный вопрос. – blueberryfields

Смежные вопросы