【问题标题】:IPC Message queue not works with forked processIPC 消息队列不适用于分叉进程
【发布时间】:2016-04-03 04:54:43
【问题描述】:

我正在尝试将 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);
    }
}

【问题讨论】:

    标签: c fork ipc


    【解决方案1】:

    问题是您正在跨进程边界发送指针。指针仅在同一进程中有效,在另一个进程中发送/使用时没有意义。实际上,您发送的是指针值,后面跟着一大堆垃圾字节,因为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);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2012-09-19
      • 2021-03-12
      • 1970-01-01
      • 2013-04-16
      • 2013-01-05
      • 2019-08-21
      • 1970-01-01
      • 2012-08-05
      • 2010-12-06
      相关资源
      最近更新 更多