使用消息队列的多进程通信

时间:2013-10-23 02:01:26

标签: c linux fork message-queue

我正在尝试实现类似于此示例的程序:

程序在4个进程中传递一个整数,每个进程递减整数

每个进程都有自己的邮箱

每个进程检查其邮箱中的变量“counter”,如果找到它将减少它

然后它将计数器变量发送到下一个过程

但程序中有一个错误,我找不到它。 请注意,这是一项任务,我只是在寻找可以帮助我找到错误的提示。

enter image description here

typedef struct {
    int counter;
    char data[256];
    int id; //id of the process that previously decremented the counter
} msg;



int main(int arqc, char *argv[]){
    int key=9;
    int id=0;
    pid_t  pid;
    int num=5;
    int    i, k;
    int arr[5];


    //create 5 forks
    if (arqc !=  2){
        num=5;
    }else{
        int ret = sscanf(argv[1], "%d", &num);
        if (ret != 1)return 0;
    }
    for(i=0 ; i<num ; i++){
        if ((pid = fork()) == -1) {
            fprintf(stderr, "can't fork, error %d\n", errno);
            exit(EXIT_FAILURE);
        }
        if (pid == 0) {
            id=i;
        }
        else {
            break;
        }
    }



    //process 1 to n comes here
    msg m;
    int boxid = msgget(id, 0600 | IPC_CREAT);
    arr[id]=boxid;
    int firstRun=1;

    //initiate the first move
    if((id==0)&&(firstRun==1)){
        m.counter = INIT_COUNTER;

        //send msg to next process
        msgsnd(arr[id], &m, sizeof(msg), 0); //send msg to own inbox
        firstRun=0;
    }



    while(1){
        //check inbox of current process
        int rec = msgrcv(arr[id], &m, sizeof(msg), 0, 0);

        printf("Im %d, counter is %d, rec is %d\n",id, m.counter, rec);


        int index;
        if(id==num){
            index=0;
        }else{
            index=id+1;
        }

        //send message to the next inbox
        int sent = msgsnd(arr[index], &m, sizeof(m), 0);

        printf( "Error opening file: %s\n", strerror( errno ) );

        sleep(1);
    }

}

2 个答案:

答案 0 :(得分:1)

您的初始msgsnd失败并且参数无效,所有内容都从那里开始。

SysV消息队列需要消息类型字段作为消息中的第一个字段,因此您需要执行类似的操作。

typedef struct
{
    long int  mtype;
    int counter;
    char data[256];
    int id; //id of the process that previously decremented the counter
} msg;

您还必须将消息设置为某些内容并在发送之前设置正确的长度。

//initiate the first move
if ((id == 0) && (firstRun == 1))
{
    m.mtype = 100;
    m.counter = INIT_COUNTER;
    strncpy(m.data, "some kind of message is nice", sizeof(m.data));
    m.id = id;

    size_t msgsize = sizeof(msg) - sizeof(long int);

    //send msg to next process
    int sent = msgsnd(arr[id], &m, msgsize, 0); //send msg to own inbox

    if (sent == -1)
    {
        perror("msgsend");
        exit(1);
    }

    firstRun = 0;
}

你遇到的问题超出了这个问题(例如在msgrcv s上设置了正确的大小),但这应该会让你超越最初的驼峰。

答案 1 :(得分:0)

首先,如果没有任何努力,那么期待SO人群为您解决问题是不合理的。目前还不清楚 问题是什么, 程序目前的行为方式,以及调试它的步骤。

抛开一边,我建议删除所有步骤,只留下两个参与者并让它在这个简单的配置中工作。一旦它工作,添加另一个,确保它仍然有效等等。