简体   繁体   English

通过FIFO传递结构

[英]Passing a structure through a FIFO

I have written a simple code where one process is passing a structure to another process, the parent process is writing the data, but child process is not able to access it. 我编写了一个简单的代码,其中一个进程将结构传递给另一个进程,父进程正在写数据,但是子进程无法访问它。 I have used fork() system call to create two processes. 我已经使用fork()系统调用来创建两个进程。 But i have problem here the parent process i called twice and child process is also called twice when i run the program. 但是我在这里遇到问题,我运行该程序时调用了两次父进程,而子进程也调用了两次。 Can any one let me know what mistake i am doing. 谁能让我知道我在做什么错误。

#include <stdlib.h>
#include <signal.h>
#include <stdio.h>
#include <errno.h>
#include <sys/errno.h>
#include <fcntl.h>
#include <string.h>

#define MAX_LINE_LEN    100
#define FIFO_NAME "my_fifo"

typedef struct student_info  {
char *name;
int age;
char *sex;
}student;

int w_byte_parent = 0, r_byte_parent = 0;
int w_byte_child = 0, r_byte_child = 0;

void do_child() {
  int fifo;
  char buffer[MAX_LINE_LEN];
  int i = 0;
  student child;

  printf("Child opening FIFO \n");
  if( (fifo = open(FIFO_NAME, O_RDWR)) < 0 )   {
    perror("open in child failed");
    exit(EXIT_FAILURE);
  }
  printf("Child  reading  from FIFO \n");
  r_byte_child = read(fifo, child, sizeof(student));
  if(r_byte_child < 0)
    printf("Read failed by child process\n");
  printf("%d Bytes read by child process\n", r_byte_child);
  }

 int main(int argc, char **argv)  {
 int fifo;
 char buffer[MAX_LINE_LEN];
 int ch = 0, i = 0;

 /*
 ** Create a FIFO
 */
 /* Parent creating FIFO */
if( (mkfifo(FIFO_NAME, 0666)) < 0)  {
    if( errno != EEXIST ) {
        perror( "mkfifo" );
        exit( EXIT_FAILURE );
    }
}
/*
 ** Create other process 
 */

switch(fork())  {
    case -1:
        perror("fork()");
        exit(EXIT_FAILURE);
    case 0: /* Child Process */
        do_child();
        break;
    default:/* Parent Process */
        break;
}
/* Pass a structure to FIFO */
student *info;
info = (student *)malloc( sizeof (student)) ;
info->name = (char *)calloc(sizeof(char), 10);
strcpy(info->name, "jack");
info->age = 27;
info->sex = (char *)calloc(sizeof(char), 10);
strcpy(info->sex , "Male");

/* Parent Opening FIFO */
printf("parent opening FIFO \n");
if( (fifo = open(FIFO_NAME,  O_RDWR)) < 0 )   {
    perror("open in parent failed");
    exit(EXIT_FAILURE);
}

/*
 ** Write some thing into FIFO so child can read it
 */
printf("parent writing to FIFO \n");
w_byte_parent = write( fifo, info, sizeof(struct student_info));
if(w_byte_parent < 0)
    printf("Nothing was written to FIFO by parent\n");
printf("Wrote %d bytes to FIFO\n",w_byte_parent);
}

Let's start with the basics. 让我们从基础开始。 Compiling your code with GCC with the -Wall option: 使用-Wall选项在GCC中编译代码:

$ gcc fifo.c -o fifo -Wall
fifo.c: In function ‘do_child’:
fifo.c:33: warning: implicit declaration of function ‘read’
fifo.c:24: warning: unused variable ‘i’
fifo.c:23: warning: unused variable ‘buffer’
fifo.c: In function ‘main’:
fifo.c:48: warning: implicit declaration of function ‘mkfifo’
fifo.c:58: warning: implicit declaration of function ‘fork’
fifo.c:88: warning: implicit declaration of function ‘write’
fifo.c:42: warning: unused variable ‘i’
fifo.c:42: warning: unused variable ‘ch’
fifo.c:41: warning: unused variable ‘buffer’
fifo.c:92: warning: control reaches end of non-void function

Ignoring all of the unused variables problems, you need to include <unistd.h> and <sys/stat.h> to get proper declarations of read , mkfifo , fork , and write . 忽略所有未使用的变量问题,您需要包括<unistd.h><sys/stat.h>以获得readmkfifoforkwrite正确声明。 Compiling again: 再次编译:

$ gcc fifo.c -o fifo -Wall -Wno-unused
fifo.c: In function ‘do_child’:
fifo.c:35: error: incompatible type for argument 2 of ‘read’
fifo.c: In function ‘main’:
fifo.c:94: warning: control reaches end of non-void function

You're passing a student instance as parameter 2 to read , but it expects a void* pointer. 您正在将一个student实例作为参数2传递给read ,但是它需要一个void*指针。 You need to pass the address of the student instance as &child . 您需要将student实例的地址传递为&child Also, it would be good to explicitly return a value form main() , although that's not strictly necessary, since failing to return a value form main() implicitly returns 0 (but only for the main() function). 同样,显式地从main()返回值将是很好的,尽管这不是严格必要的,因为未能从main()返回值的形式隐式返回0(但对于main()函数)。

But even with those errors corrected, you still see the output of the parent process twice. 但是即使纠正了这些错误,您仍然可以看到父进程的输出两次。 Why? 为什么? Because both the parent and the child processes are executing the code block below the switch statement. 因为父进程和子进程都在执行switch语句下面的代码块。 The child process calls the do_child() function and never exits, so it returns and continues executing. 子进程将调用do_child()函数,并且永不退出,因此它将返回并继续执行。

The simple fix to that is make sure to exit the child process, either at the end of do_child() , or immediately after the call returns, eg 对此的简单解决方法是确保在do_child()的末尾或调用返回后立即退出子进程,例如

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

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