我编写了一个简单的代码,其中一个进程将结构传递给另一个进程,父进程正在编写数据,但子进程无法访问它。我使用fork()
系统调用来创建两个进程。但我在这里遇到问题,我调用了两次父进程,当我运行程序时,子进程也被调用了两次。谁能让我知道我在做什么错误。
#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);
}
答案 0 :(得分:3)
让我们从基础开始。使用-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
忽略所有未使用的变量问题,您需要包含<unistd.h>
和<sys/stat.h>
才能正确声明read
,mkfifo
,fork
和write
。再次编译:
$ 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
您将student
实例作为参数2传递给read
,但它需要void*
指针。您需要将student
实例的地址作为&child
传递。此外,显式返回值形式main()
会很好,尽管这不是绝对必要的,因为未能返回值main()
形式会隐式返回0(但仅 main()
函数。)
但即使纠正了这些错误,您仍然会看到父进程的输出两次。为什么?因为父进程和子进程都在执行switch语句下面的代码块。子进程调用do_child()
函数并且永不退出,因此返回并继续执行。
对此的简单修复是确保在do_child()
结束时或在呼叫返回后立即退出子进程,例如