2017-01-20 29 views
1

次のコードでは、子c2が完了するまで(:c2)、子供c1ブロック(パイプ経由)が必要です。しかし、それは動作しません。 c1は永遠にブロックされます。私がpipe_close()c2の外に移動し、それを親に入れると動作します。兄弟の子プロセス間のパイプシェア

これは、親から作成されたパイプが兄弟の子プロセス間で共有できないためですか?

#include <stdio.h> 
#include <errno.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <stdarg.h> 

static void pipe_close(int *); 
static void pipe_read(int *); 

int 
main(void) 
{ 
    int pp_main[2] = {-1, -1}; 
    pipe(pp_main); 

    int ppid = getpid(); 
    int pgid = getpgrp(); 

    int pid_c1 = fork(); 
    if (pid_c1 == 0) 
    { // in child c1 
     int cpid_c1 = getpid(); 
     int gid = getpgrp(); 
     printf("[c1][%d][%d] is made, wait pipe ready\n", cpid_c1, gid); 
     pipe_read(pp_main); 
     printf("[c1][%d][%d] done\n", cpid_c1, gid); 
    } 
    else 
    { // in parent 
     printf("[main][%d][%d] created child c1: %d\n", ppid, pgid, pid_c1); 
     int pid_c2 = fork(); 
     if (pid_c2 == 0) 
     { // in child c2 
      int cpid_c2 = getpid(); 
      int gid = getpgrp(); 
      printf("[c2][%d][%d] is made\n", cpid_c2, gid); 
      for (int i = 2; i > 0; --i) 
      { 
       printf("[c2][%d][%d] count down %d\n", cpid_c2, gid, i); 
       sleep(1); 
      } 
      pipe_close(pp_main); 
      printf("[c2][%d][%d] done\n", cpid_c2, gid); 
     } 
     else 
     { // in parent 
      printf("[main][%d][%d] created child c2: %d\n", ppid, pgid, pid_c2); 
     } 
     int status; 
     waitpid(pid_c2, &status, 0); 
    } 

    int status; 
    waitpid(pid_c1, &status, 0); 
    return 0; 
} 

static void 
pipe_read(int *pp) 
{ 
    char ch; 
    if (pp[1] >= 0) 
    { 
     close (pp[1]); 
     pp[1] = -1; 
    } 
    if (pp[0] >= 0) 
    { 
     while (read (pp[0], &ch, 1) == -1 && errno == EINTR); 
    } 
} 

static void 
pipe_close(int *pp) 
{ 
    if (pp[0] >= 0) 
     close (pp[0]); 
    if (pp[1] >= 0) 
     close (pp[1]); 
    pp[0] = pp[1] = -1; 
} 

答えて

1

私はC2のうち、pipe_close()を移動し、親にそれを置く場合、それは動作します。

これは予想される動作です。 がすべての参照が閉じられるまで、パイプは完全に閉じていません。あなたのコードのpipeは、forkの前に作成されています。したがって、親プロセスと子プロセスの両方がそのパイプをオープンしています。 c2の子は終了し、パイプへの参照を閉じます。ただし、親プロセスは、c1が終了するのを待ってブロックします。親プロセスが明示的または暗黙的に(終了によって)パイプを閉じることはないので、これは決して起こりません。

+0

ああ、これはすべてを説明します!どうもありがとう! – mitnk