2011-07-29 7 views
1

파이프를 통해 서로 메시지를 보내고 종료하는 두 개의 자식 프로세스를 생성하는 코드를 작성하려고합니다. 그러나 다음 코드를 실행하면 child2 만 인사말을 인쇄하지만 자식 1은 자식 2가 자식 1이 아닌 메시지를 여전히 인쇄합니다.두 자식 프로세스간에 파이프로 통신하기

아무도 내 방법론에 문제가 있음을 알고 있습니까?

#include <string.h> 
#include <stdlib.h> 
#include <stdio.h> 
#include <sys/types.h> 
#include <unistd.h> 

int main(int argc, char** argv) { 
    char chld_1_send[20] = "hello from child 1"; 
    char chld_1_recv[20]; 
    char chld_2_send[20] = "hi from child 2"; 
    char chld_2_recv[20]; 

    int chld_1_outgoing[2]; 
    int chld_2_outgoing[2]; 

    pipe(chld_1_outgoing); 
    pipe(chld_2_outgoing); 

    int chld_1_status, chld_2_status; 
    pid_t chld_1, chld_2; 

    chld_1 = fork(); 

    if(chld_1 == 0) { 
     chld_2 = fork(); 
    } 

    if(chld_1 == 0 && chld_2 == 0) { 
     printf("parent [pid:%d] waiting on both children to finish\n", getpid()); 

     while(wait(&chld_1_status) != chld_1 && wait(&chld_2_status) != chld_2) {} 

     printf("done waiting\n"); 
    } 
    else if(chld_1 != 0 && chld_2 == 0) { 
     printf("this is child 1 [pid:%d] with parent [pid:%d]\n", getpid(), getppid()); 

     write(chld_1_outgoing[1], chld_1_send, strlen(chld_1_send)); 
     while(read(chld_1_outgoing[0], &chld_1_recv, sizeof(chld_2_recv)) < 0) {} 

     printf("child 2 said '%s'\n", chld_1_recv); 
     exit(0); 
    } 
    else if(chld_2 != 0 && chld_1 == 0) { 
     printf("this is child 2 [pid:%d] with parent [pid:%d]\n", getpid(), getppid()); 

     write(chld_2_outgoing[1], chld_2_send, strlen(chld_2_send)); 
     while(read(chld_2_outgoing[0], &chld_2_recv, sizeof(chld_2_recv)) < 0) {} 

     printf("child 1 said '%s'\n", chld_2_recv); 

     exit(0); 
    } 

    printf("both children have terminated successfully\n"); 

    return 0; 
} 

그러나 터미널이 밖으로이 명령 인쇄를 실행하면 무한 루프로 전환 :

$ this is child 2 [pid:15713] with parent [pid:1] 
child 1 said 'hi from child 2' 
parent [pid:15714] waiting on both children to finish 
+0

http://developers.sun.com/solaris/articles/named_pipes.html – Anders

+0

어쨌든 명명 된 파이프없이이 작업을 수행 할 수 있습니까? 한 파이프가 다른 아이와 통신 할 수 있다는 것을 의미합니다. – David

+0

waitpid 호출을 대기로 변경했습니다. 그러나 이제 프로그램은 무한 루프로 진행됩니다. – David

답변

2

다음은 확실히 개선 될 수 있지만 시작할 수 있어야 간단한 예입니다. 자세한 내용은 Link1Link2을 참조하십시오.

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <sys/wait.h> 
#include <unistd.h> 

/* max receiving buffer size; Note: no check or enforcement is made on this value*/ 
#define BUF_SIZE 256 

int main() 
{ 
    int pfd1[2]; 
    int pfd2[2]; 

    ssize_t numRead = -1; 
    /* Note: working under the assumption that the messages 
     are of equal length*/ 
    const char* messageOne = "Hello from child ONE.\n"; 
    const char* messageTwo = "Hello from child TWO.\n"; 

    const unsigned int commLen = strlen(messageOne) + 1; 

    char buf[BUF_SIZE]; 

    if (pipe(pfd1) == -1) 
    { 
     printf("Error opening pipe 1!\n"); 
     exit(1); 
    } 

    if (pipe(pfd2) == -1) 
    { 
     printf("Error opening pipe 2!\n"); 
     exit(1); 
    } 

    printf("Piped opened with success. Forking ...\n"); 

    // child 1 
    switch (fork()) 
    { 
     case -1: 
      printf("Error forking child 1!\n"); 
      exit(1); 

     case 0: 
      printf("\nChild 1 executing...\n"); 
      /* close reading end of first pipe */ 
      if (close(pfd1[0]) == -1) 
      { 
       printf("Error closing reading end of pipe 1.\n"); 
       _exit(1); 
      } 
      /* close writing end of second pipe */ 
      if (close(pfd2[1]) == -1) 
      { 
       printf("Error closing writing end of pipe 2.\n"); 
       _exit(1); 
      } 

      /* write to pipe 1 */ 
      if (write(pfd1[1], messageOne, commLen) != commLen) 
      { 
       printf("Error writing to pipe 1.\n"); 
       _exit(1); 
      } 

      if (close(pfd1[1]) == -1) 
      { 
       printf("Error closing writing end of pipe 1.\n"); 
       _exit(1); 
      } 

      /* reding from pipe 2 */ 
      numRead = read(pfd2[0], buf, commLen); 
      if (numRead == -1) 
      { 
       printf("Error reading from pipe 2.\n"); 
       _exit(1); 
      } 

      if (close(pfd2[0]) == -1) 
      { 
       printf("Error closing reding end of pipe 2.\n"); 
       _exit(1); 
      } 

      printf("Message received child ONE: %s", buf); 
      printf("Exiting child 1...\n"); 
      _exit(0); 

     default: 
      break; 
    } 

    // child 2 
    switch (fork()) 
    { 
     case -1: 
      printf("Error forking child 2!\n"); 
      exit(1); 
     case 0: 
      printf("\nChild 2 executing...\n"); 
      /* close reading end of second pipe */ 
      if (close(pfd2[0]) == -1) 
      { 
       printf("Error closing reading end of pipe 2.\n"); 
       _exit(1); 
      } 
      /* close writing end of first pipe */ 
      if (close(pfd1[1]) == -1) 
      { 
       printf("Error closing writing end of pipe 1.\n"); 
       _exit(1); 
      } 

      /* read from the first pipe */ 
      if (read(pfd1[0], buf, commLen) == -1) 
      { 
       printf("Error reading from pipe 1.\n"); 
       _exit(EXIT_FAILURE); 
      } 

      if (close(pfd1[0]) == -1) 
      { 
       printf("Error closing reading end of pipe 1.\n"); 
       _exit(EXIT_FAILURE); 
      } 

      /* write to the second pipe */ 
      if (write(pfd2[1], messageTwo, commLen) != commLen) 
      { 
       printf("Error writing to the pipe."); 
       _exit(EXIT_FAILURE); 
      } 

      if (close(pfd2[1]) == -1) 
      { 
       printf("Error closing writing end of pipe 2."); 
       _exit(EXIT_FAILURE); 
      } 

      printf("Message received child TWO: %s", buf); 
      printf("Exiting child 2...\n"); 
      _exit(EXIT_SUCCESS); 

     default: 
      break; 
    } 

    printf("Parent closing pipes.\n"); 

    if (close(pfd1[0]) == -1) 
    { 
     printf("Error closing reading end of the pipe.\n"); 
     exit(EXIT_FAILURE); 
    } 

    if (close(pfd2[1]) == -1) 
    { 
     printf("Error closing writing end of the pipe.\n"); 
     exit(EXIT_FAILURE); 
    } 

    if (close(pfd2[0]) == -1) 
    { 
     printf("Error closing reading end of the pipe.\n"); 
     exit(EXIT_FAILURE); 
    } 

    if (close(pfd1[1]) == -1) 
    { 
     printf("Error closing writing end of the pipe.\n"); 
     exit(EXIT_FAILURE); 
    } 

    printf("Parent waiting for children completion...\n"); 
    if (wait(NULL) == -1) 
    { 
     printf("Error waiting.\n"); 
     exit(EXIT_FAILURE); 
    } 

    if (wait(NULL) == -1) 
    { 
     printf("Error waiting.\n"); 
     exit(EXIT_FAILURE); 
    } 

    printf("Parent finishing.\n"); 
    exit(EXIT_SUCCESS); 
} 
+0

두 번째 fork 명령은 child1과 parent 모두에서 실행됩니다. 그게 문제를 만들지 않겠습니까? – Mani

0

귀하의 논리는 주어진 프로세스가 부모인지 또는 하위인지 판단하기위한 것입니다. 아이는 0fork에서 얻고, 부모는 아이의 pid를 얻습니다.

if(chld_1 != 0) 

을 그리고, 부모가 모두 chld_1chld_2가 0이되는 과정이어야한다 :

if(chld_1 != 0 && chld_2 != 0) 
아마도 당신은 두 아이들이 처음 if가 있어야하는 경우에 같은 부모를 갖고 싶어

또한 fork (모두 -1이면 오류) 오류 검사를 수행해야합니다.

관련 문제