为什么msgsnd()和msgrcv()无法正常运行?

时间:2018-06-01 05:34:38

标签: linux process ipc message-queue msgrcv

msgsnd()和msgrcv()属于同一个函数,它与第一个例子一样。

的main.c

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="one-more-container">
<div id="post" class="single-featured-background" style="background-image: url('<?php echo $thumb['0'];?>')">
    <div class="super-title-container">
        <h1 class="super-title"><?php the_title(); ?></h1>
        <div class="description-container">
            <h2><?php the_field('antraste'); ?></h2>
            <p><?php the_field('aprasymas'); ?></p>
        </div>      
    </div>
</div>

comproc.c

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>


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

    pid_t pid1;
    pid_t pid2;
    pid_t pid3;
    pid_t pid4;

    if ((pid1 = fork()) < 0) {
        printf("fork error\n");
    } else if (pid1 == 0){
        printf("I am in First process\n");
        int nodeId = 1;
        //cmc_init(nodeId);
        test2(nodeId);
        return 0;

    }

    if ((pid2 = fork()) < 0) {
        printf("fork error\n");
    } else if (pid2 == 0){
        printf("I am in second process\n");
        int nodeId = 2;
        //cmc_init(nodeId);
        test2(nodeId);
        return 0;

    } 

    if ((pid3 = fork()) < 0) {
        printf("pid3 fork error\n");
    } else if (pid3 == 0) {
        printf("I am in Third process\n");
        int nodeId = 3;
        //cmc_init(nodeId);
        test2(nodeId);
        return 0;
    } 

    if ((pid4 = fork()) < 0) {
        printf("pid4 fork error\n");
    } else if (pid4 == 0) {
        printf("I am in Fourth process\n");
        int nodeId = 4;
        //cmc_init(nodeId);
        //test2(nodeId);
        return 0;
    } 

    if (waitpid(-1, NULL, 0) < 0) {
        printf("wait1 error\n");
    }   
    sleep(3);


    return 0;
}

效果很好,结果是:

typedef struct Msg_context {
    int nodeId;

} Msg_context;
void test2(int nodeId)
{
    int i = 1;
    for (i = 1; i <= 3; i++) {
        if (i == nodeId) {
            continue;
        }
        int msgid = -1;
        Msg_context msgSend;

        msgid = msgget((key_t)i, 0666 | IPC_CREAT);


        if (msgid == -1) {
            printf("msgid == -1\n");
        }

        msgSend.nodeId = nodeId;
        if (msgsnd(msgid, (void *)&msgSend, 4, 0) == -1) {
            printf("send message error\n");
        }
    }

    //com_process_send(nodeId);

    sleep(1);
    while (1) {
        //com_process_recv(nodeId);
        int msgrecvId = -1;
        Msg_context msgRecv;
        msgrecvId = msgget((key_t)nodeId, 0666 | IPC_CREAT);


        if (msgrecvId == -1) {
            printf("msgrecvId == -1\n");
        }

        if (msgrcv(msgrecvId, (void *)&msgRecv, BUFSIZ, 0, 0) == -1) {
            printf("send message error\n");
        }
        printf("[recv] nodeId = %d, recv.nodeId = %d\n", nodeId, msgRecv.nodeId);

    }


}

但是当我把msgrcv()放到另一个函数中时,它无法正常工作。 像这样:

comproc.c

I am in First process
[recv] nodeId = 2, recv.nodeId = 1
[recv] nodeId = 3, recv.nodeId = 1
I am in second process
[recv] nodeId = 1, recv.nodeId = 2
[recv] nodeId = 3, recv.nodeId = 2
I am in Third process
[recv] nodeId = 1, recv.nodeId = 3
[recv] nodeId = 2, recv.nodeId = 3
I am in Fourth process

结果如下:

typedef struct Msg_context {
    int nodeId;

} Msg_context;
int com_process_recv(int nodeId)
{

    int msgrecvId = -1;
    Msg_context msgRecv;
    msgrecvId = msgget((key_t)nodeId, 0666 | IPC_CREAT);


    if (msgrecvId == -1) {
        printf("msgrecvId == -1\n");
    }

    if (msgrcv(msgrecvId, (void *)&msgRecv, BUFSIZ, 0, 0) == -1) {
        printf("send message error\n");
    }
    printf("[recv] nodeId = %d, recv.nodeId = %d\n", nodeId, msgRecv.nodeId);



}
void test2(int nodeId)
{
    int i = 1;
    for (i = 1; i <= 3; i++) {
        if (i == nodeId) {
            continue;
        }
        int msgid = -1;
        Msg_context msgSend;

        msgid = msgget((key_t)i, 0666 | IPC_CREAT);


        if (msgid == -1) {
            printf("msgid == -1\n");
        }

        msgSend.nodeId = nodeId;
        if (msgsnd(msgid, (void *)&msgSend, 4, 0) == -1) {
            printf("send message error\n");
        }
    }

    //com_process_send(nodeId);

    sleep(1);
    while (1) {
        com_process_recv(nodeId);


    }


}

或者像这样:

I am in First process
[recv] nodeId = 2, recv.nodeId = 1
I am in second process
[recv] nodeId = 1, recv.nodeId = 2
[recv] nodeId = 3, recv.nodeId = 2
I am in Third process
[recv] nodeId = 2, recv.nodeId = 3
[recv] nodeId = 1, recv.nodeId = 3
I am in Fourth process

但是,如果我也把msgsnd()放到另一个函数中,它又能很好地工作。

comproc.c

I am in First process
[recv] nodeId = 2, recv.nodeId = 1
[recv] nodeId = 3, recv.nodeId = 3, ret = 4
I am in second process
[recv] nodeId = 1, recv.nodeId = 2
[recv] nodeId = 3, recv.nodeId = 2
I am in Third process
[recv] nodeId = 1, recv.nodeId = 3
[recv] nodeId = 2, recv.nodeId = 3
I am in Fourth process

所以这很奇怪,对吗?我不明白为什么会这样。所以我很希望你们能帮助我理解这一点。非常感谢你!!!

1 个答案:

答案 0 :(得分:0)

根据我在您的评论中所读到的内容,如果您希望不同的流程只读取发给他们的邮件,您应该查看msgtyp

msgrcv()个参数

从手册页:

  

ssize_t msgrcv(int msqid,void * msgp,size_t msgsz,long msgtyp,                  int msgflg);

     

参数msgtyp指定请求的消息类型,如下所示:

     

如果msgtyp为0,则读取队列中的第一条消息。

     

如果msgtyp大于0,则读取队列中msgtyp类型的第一条消息,除非在msgflg中指定了MSG_EXCEPT,在这种情况下,将读取队列中不等于msgtyp的第一条消息。 / p>      

如果msgtyp小于0,则将读取队列中具有小于或等于msgtyp绝对值的最低类型的第一条消息。

在您的情况下,请致电

    msgrcv(msgrecvId, (void *)&msgRecv, BUFSIZ, 0, nodeId) == -1)

将帮助您从第一个消息队列读取第一个进程,从第二个msq进行第二个进程等等...