简体   繁体   English

错误地使用fork()?

[英]Using fork() incorrectly?

I'm trying to use fork() to implement a message queue. 我正在尝试使用fork()实现消息队列。 Here's what I've got. 这就是我所拥有的。

#define DATA_SIZE 256
#define BUFF_SIZE 4096

int main(void) {
    // seed the random number generator
    srand(time(NULL));

    // Parent and Ground Truth Buffers
    char ground_truth[BUFF_SIZE]    = {0};  // used to verify
    char producer_buffer[BUFF_SIZE] = {0};  // used by the parent
    int i = 0;  
    int msqid = 0;
    int rc;
    pid_t msq_pid;

    for (i = 0; i < BUFF_SIZE; ++i) {
        producer_buffer[i] = ground_truth[i] = rand() % 256;
    }

    const key_t s_msq_key = 1337;  // used to create message queue ipc
    const char *const p_msq_key = "/OS_MSG";

    msqid = msgget(s_msq_key, IPC_CREAT | 0660);

    msq_pid = fork();

    if(msq_pid == -1){
       perror("error forking");
       exit(1);
    }

    if(msq_pid > 0){
        rc = msgsnd(msqid, (void*)p_msq_key, sizeof(producer_buffer), 0);
        printf("MESSAGE SENT\n");
        if(rc < 0){
            perror("message send failed");
            exit(1);
        }
        return 1;
    } else {
        if(memcmp(producer_buffer, ground_truth, DATA_SIZE) == 0){
            printf("MESSAGE REC");
            return 1;
        }
        exit(1);
    }

return 0;
}

I added my actual problem. 我添加了我的实际问题。 Hopefully this isn't too much. 希望这不是太多。 This is a homework assignment but I didn't want to just get help with the code. 这是一项家庭作业,但我不想仅仅获得代码方面的帮助。 Once again, the only result that I am getting is MESSAGE REC rather than MESSAGE SENT followed by MESSAGE REC 再一次,我得到的唯一结果是MESSAGE REC而不是MESSAGE SENT之后是MESSAGE REC

EDIT: 编辑:

Okay, I added an error check for msq_pid == -1 . 好的,我为msq_pid == -1添加了一个错误检查。 I also noticed that when I restarted my Virtual Machine, I was able to get both MESSAGE SENT and MESSAGE REC . 我还注意到,当我重新启动虚拟机时,能够同时收到MESSAGE SENTMESSAGE REC After several more runs of the program, I then began only receiving MESSAGE REC . 在该程序再运行几次之后,我才开始仅接收MESSAGE REC Can someone explain this? 有人可以解释吗?

Per the fork() man page it seems your problem is that you have the child and parent inverted. fork()手册页上,似乎您的问题是孩子和父母的关系倒了。 fork() returns 0 to the child process, it returns > 0 to the parent, and returns -1 on error. fork()向子进程返回0,向父进程返回> 0,并在错误时返回-1。 So in your code you should have: 因此,在您的代码中,您应该具有:

if(msg_pqid == 0) { 
     /* The child sends the message */ 
} else { 
    /* Parent receives the message */ 
}

I prefer to use a switch like so: 我更喜欢使用这样的开关:

switch ((msg_pqid = fork())) {
case -1: 
    /* Error */
case 0:
    /* Child sends message */
default:
    /* Parent receives message */
}

several of the system calls are being used incorrectly. 几个系统调用使用不正确。

The returned status from several of the system calls are being ignored 从多个系统调用返回的状态将被忽略

The following code: 如下代码:

  1. cleanly compiles 干净地编译
  2. performs the desired operation 执行所需的操作
  3. handles all the error conditions 处理所有错误情况

now, the code: 现在,代码:

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

#include <time.h>    //time()

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

#include <unistd.h>  //fork()

#include <string.h>  //memcmp()


#define MAX_MSG_LEN (10)
#define ACT_MSG_LEN (8)

// Parent and Ground Truth Buffers
struct msgbuf
{
    long mtype;       /* message type, must be > 0 */
    char mtext[ MAX_MSG_LEN ];    /* message data */
};

struct msgbuf ground_truth;  // used to verify
struct msgbuf producer_buffer = {1,"message"}; // used by the parent

int main(void)
{
    // seed the random number generator
    srand((unsigned)time(NULL));



    //int i = 0;
    int msqid = 0;
    int rc;
    pid_t msq_pid;
    ssize_t rcvStatus;

    const key_t s_msq_key = 1337;  // used to create message queue ipc
    //const char *const p_msq_key = "/OS_MSG";

    msqid = msgget(s_msq_key, IPC_CREAT | 0660);
    if( -1 == msqid )
    {// then msgget failed
        perror( "msgget failed");
        exit( EXIT_FAILURE );
    }

    // implied else, msgget successful

    msq_pid = fork();

    while(1)
    {
        switch( msq_pid )
        {
            case -1:
                perror("error forking");
                exit( EXIT_FAILURE );
                break;

            default:  // parent process
                rc = msgsnd(msqid, &producer_buffer, sizeof producer_buffer, 0);
                printf("MESSAGE SENT: %s\n", producer_buffer.mtext);
                if(rc < 0)
                {
                    perror("message send failed");
                    exit( EXIT_FAILURE );
                }
                break;

            case 0:   // child process
                rcvStatus = msgrcv( msqid, &ground_truth, sizeof( ground_truth ), 0, 0);
                if( -1 == rcvStatus )
                { // then msgrcv failed
                    perror( "msgrcv failed" );
                    exit( EXIT_FAILURE );
                }

                // implied else, msgrcv successful

                if(memcmp(producer_buffer.mtext, ground_truth.mtext, ACT_MSG_LEN) == 0)
                {
                    printf("MESSAGE REC %s\n", ground_truth.mtext);
                }

                else
                {
                    printf( "msg Sent: '%s' does not match msg Recv: '%s'\n", producer_buffer.mtext, ground_truth.mtext);
                }
                break;
        } // end switch
    } // end while forever
} // end function: main

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

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