系统V消息队列故障

时间:2015-09-19 16:26:34

标签: c++ linux posix ipc message-queue

我在使用System V Message Queue设置并在Linux上正常工作时遇到了一些麻烦。我们的想法是让一个中心节点从其他几个节点中提取数据。问题是中央节点最终坐在那里等待其他节点发送消息。我查看了邮箱的值,它们在所有进程中都是相同的。 I.E. 0表示中央邮箱,32769表示其他进程1,等等。我不知道它为什么会失败。我试图将msgrcv中的priority参数更改为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[]){

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

1 个答案:

答案 0 :(得分:0)

您正在使用系统V api,这可能不是您想要的。有关详细信息,请参见此处:

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

msgget,msgctl,msgsnd,msgrcv命令是较旧的系统V api的一部分,虽然语义相似,但不是posix队列。几个快速谷歌搜索系统V队列教程/示例可能会解决您的问题。

如果您真的想要使用posix队列,请切换到mq_open,mq_close,mq_unlink,mq_send,mq_receive,mq_getattr,mq_setattr api上查找文档。