2017-12-12 26 views
0

내 프로그램의 목표는 서로 파이프를 읽고 쓰는 것을 의사 소통하는 두 개의 파이프와 두 개의 프로세스를 만드는 것입니다.파이프()와 포크()

  1. 프로세스 P1은 배관 (C1)로부터 판독하고
  2. 프로세스 P2가 파이프 (C2)로부터 판독하고, 파이프로부터 판독 수가 BIG_INT_STOP 미만까지 파이프 C1

에 기록 파이프 C2 쓰는 두 프로세스는 파이프의 수를 계속 증가시킵니다. 이 조건이 참하자마자 그것을 읽는 첫 번째 프로세스가 파이프를 닫고 종료하고 번호를 인쇄합니다. 문제는 프로세스 p2가 p1 이전에 끝나면 프로세스 p1이 작동하고 프로세스 p1이 p2 전에 끝나면 루프가됩니다. 이유를 설명해 주시겠습니까?

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <sys/sysinfo.h> 
#include <sys/wait.h> 
#include <errno.h> 
#include <time.h> 
#include <string.h> 
#define BIG_INT_STOP 40 
#define TEST_ERROR if (errno) {fprintf(stderr, \ 
        "%s:%d: PID=%5d: Error %d (%s)\n", \ 
        __FILE__,   \ 
        __LINE__,   \ 
        getpid(),   \ 
        errno,   \ 
        strerror(errno));} 

int main(){ 
    int c1[2], c2[2], p1, p2, z; 
    long a = 0, c; 
    pipe(c1); 
    pipe(c2); 
    write(c1[1], &a, sizeof(a)); 
    write(c2[1], &a, sizeof(a)); 
    p1 = fork(); 
    p2 = fork(); 
    switch(p1){ 
    case -1: 
     TEST_ERROR; 
     exit(EXIT_FAILURE); 
    case 0: 
     read(c1[0], &c, sizeof(c)); 
     while(c != BIG_INT_STOP){ 
     ++c; 
     write(c2[1], &c, sizeof(c)); 
     read(c1[0], &c, sizeof(c)); 
     } 
     close(c1[0]); 
     close(c1[1]); 
     close(c2[0]); 
     close(c2[1]); 
     printf("p1: %ld\n", c); 
     exit(0); 
    } 
    switch(p2){ 
    case -1: 
     TEST_ERROR; 
     exit(EXIT_FAILURE); 
    case 0: 
     read(c2[0], &c, sizeof(c)); 
     while(c != BIG_INT_STOP){ 
     ++c; 
     write(c1[1], &c, sizeof(c)); 
     read(c2[0], &c, sizeof(c)); 
     } 
     close(c1[0]); 
     close(c1[1]); 
     close(c2[0]); 
     close(c2[1]); 
     printf("p2: %ld\n", c); 
     exit(0); 
    } 
    while(wait(&z) != -1); 
} 
+0

쓰기 바이트 및/또는 오류 코드에 대해 '쓰기'및 '읽기'결과를 확인하지 않았을 수 있습니다. – Marian

+0

2 개의 프로세스가 프로그램 실행 종료시 항상 번호를 인쇄하므로 오류가 발생하는 이유는 무엇입니까? – Lorenzo

답변

3

프로그램이 약간 이상합니다. 주된 문제는 두 번째 포크가 주 프로그램과 첫 번째 자식 모두에서 실행된다는 것입니다. 실제로 당신은 네 가지 과정을 진행하고 있습니다 : 주된 두 명의 아들과 첫 아들의 아들. 이것은 아마도 당신이 원하는 것이 아닙니다. 첫 번째 fork 다음에 첫 번째 switch을 넣고 주 프로그램에서만 두 번째 fork을 실행하고 싶을 것입니다.

예기치 않은 상황에 대해 readwrite의 결과 값을 확인하지 않습니다.

1

문제는 p2가 2 번 분기됩니다. 부모 프로세스에 한 번, p1 프로세스에서 두 번째

대신에 :

p1 = fork(); 
    p2 = fork(); 

당신은 다음과 같이 작성해야합니다 :

p1 = fork(); 
if (p1 > 0) { 
     p2 = fork(); 
} 
0

귀하의 코드가있는 경우 즉 readwrite에 대한 호출에 대한 적절한 검사 오류가 발생하지 않습니다 파이프에서 읽는 것이 어려울 때, 어린이는 c의 값이 절대 종료 값에 도달하지 않으므로 결코 끝나지 않는 루프를 입력하게됩니다.

자식 프로세스가 끝나면 파이프가 닫히기 때문에 한 프로세스가 파이프를 닫고 다른 프로세스가 파이프를 닫은 후에 가장 최근 값인 c으로 들어갈 수있는 경쟁 조건을 입력 할 확률이 매우 높습니다. 이 작업은 3 개 하위 프로세스와 결국 같은 현재 fork로 통화의 배치에 의해 혼합되어 있지 2.

당신이 그 시점에서 당신은 단지에있을 수 있다는 것을 알고 당신은 switchfork에 두 번째 전화를 이동해야

부모 프로세스를 종료하고 파이프 닫음을 부모 프로세스로 이동합니다.

+0

많은 것을 감사하지만 "쓰기"또는 "읽기"를 할 때마다 컨트롤을 사용해야합니까? – Lorenzo

+0

이 경우 확실히, 읽은 내용은 while 루프를 제어하는 ​​것과 직접 관련이 있습니다. –