1

あるプロセスが構造体を別のプロセスに渡し、親プロセスがデータを書き込んでいるが、子プロセスがそれにアクセスできない単純なコードを作成しました。fork()システム コールを使用して 2 つのプロセスを作成しました。しかし、プログラムを実行すると、親プロセスが2回呼び出され、子プロセスも2回呼び出されるという問題があります。誰でも私がやっている間違いを教えてもらえますか?

#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);
}
4

1 に答える 1

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>readmkfifoforkwrite

$ 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*ポインターが必要です。インスタンスのアドレスをとして渡す必要があります。また、値フォームを返さないと暗黙的に 0 が返されるため (ただし、関数の場合のみ) 、値フォームを明示的に返すとよいでしょう。ただし、これは厳密には必要ではありません。student&childmain()main()main()

しかし、これらのエラーを修正しても、親プロセスの出力が 2 回表示されます。なんで?親プロセスと子プロセスの両方が、switch ステートメントの下のコード ブロックを実行しているためです。子プロセスはdo_child()関数を呼び出して終了しないため、戻り、実行を継続します。

do_child()これに対する簡単な修正は、 の最後または呼び出しが返された直後に、必ず子プロセスを終了することです。

于 2013-09-11T02:11:09.780 に答える