繁体   English   中英

IPC消息队列不适用于分叉进程

[英]IPC Message queue not works with forked process

我正在尝试使用带有分叉进程的IPC消息队列,将指针传递给动态分配的字符串,但它不起作用。

这是我做的一个简单的测试。 它不会打印从队列接收的字符串。 但是,如果我尝试删除fork()它完美地工作。

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

#define MSGSZ     128

typedef struct msgbuf {
    long    mtype;
    char    *mtext;
} message_buf;

int
main ()
{
    int msqid;
    char *p;
    key_t key = 129;

    message_buf sbuf, rbuf;
    p = (char *) malloc(sizeof(char) * MSGSZ);

    if ((msqid = msgget(key, IPC_CREAT|0666)) < 0) {
        perror("msgget");
        exit(1);
    }

    if (fork() == 0) {
        strcpy(p, "Did you get this?");
        sbuf.mtype = 1;
        sbuf.mtext = p;

        if (msgsnd(msqid, &sbuf, MSGSZ, IPC_NOWAIT) < 0) {
            perror("msgsnd");
            exit(1);
        }
    }
    else {
        sleep(1);

        if (msgrcv(msqid, &rbuf, MSGSZ, 0, 0) < 0) {
            perror("msgrcv");
            exit(1);
        }

        printf("Forked version: %s\n", rbuf.mtext);
        msgctl(msqid, IPC_RMID, NULL);
    }
}

问题是您正在跨进程边界发送指针。 指针仅在同一过程中有效,并且在另一个过程中发送/使用时无意义。 实际上,您发送指针值后跟一大堆垃圾字节,因为msgbuf.mtext实际上不是MSGSZ字节大小(因此在技术上调用未定义的行为)。

您需要做的是在消息中内联声明缓冲区。 也就是说,将message_buf定义更改为:

typedef struct msgbuf {
    long    mtype;
    char    mtext[MSGSZ];
} message_buf;

然后strcpy直接进入mtext

strcpy(sbuf.mtext, "Did you get this?");

为清楚起见,下面是完整的程序,其中描述了更改:

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

#define MSGSZ     128

typedef struct msgbuf {
    long    mtype;
    char    mtext[MSGSZ];
} message_buf;

int
main (void)
{
    int msqid;
    key_t key = 129;

    message_buf sbuf, rbuf;

    if ((msqid = msgget(key, IPC_CREAT|0666)) < 0) {
        perror("msgget");
        exit(1);
    }

    if (fork() == 0) {
        strcpy(sbuf.mtext, "Did you get this?");
        sbuf.mtype = 1;

        if (msgsnd(msqid, &sbuf, MSGSZ, IPC_NOWAIT) < 0) {
            perror("msgsnd");
            exit(1);
        }
    }
    else {
        sleep(1);

        if (msgrcv(msqid, &rbuf, MSGSZ, 0, 0) < 0) {
            perror("msgrcv");
            exit(1);
        }

        printf("Forked version: %s\n", rbuf.mtext);
        msgctl(msqid, IPC_RMID, NULL);
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM