2014-04-16 5 views
0

나는 자식 프로세스를 만드는 데 fork()을 사용하는 프로그램을 가지고 있으며, 아이들이 유닉스 파이프를 사용하여 부모 프로세스와 다시 통신하도록하고 싶습니다.어떻게 유닉스 파이프를 동적으로 생성합니까?

문제는 다중 파이프가 생성되지 않았거나 배열에 문제가있는 것입니다. 부모 프로그램에서 prinf()을 사용할 때 각 자식이 다른 데이터를 보내더라도 모든 파이프에서 동일한 데이터를 읽습니다.

여기 내 코드입니다 : 내 의견에 언급 한 바와 같이

// Variables 
int pipes_count = 0; 
int *pipes[MAXCLIENTS]; 
int new_pipefd[2]; 
int pipe_bytes; 
char pipe_buffer[MAXDATASIZE]; 

while(1) { 
    // Pipe creation 
    pipe(new_pipefd); 
    pipes[pipes_count] = new_pipefd; 
    pipes_count++; 

    if (fork()) { 
     // unrelated code for parent here 
     close(new_pipefd[1]); // close the parent's write-end of the pipe 
     break; 
    } else { 
     // unrelated code for child here 
     close(new_pipefd[0]); // close the child's read-end of the pipe 
     break; 
    } 

    if (some condition) { break; } // The parent will stop creating pipes 
} 

while(condition that guarantees this is the child) { 
    write(new_pipefd[1], buffer, strlen(recv_buffer)); 
    close(new_pipefd[1]); 
    return 0; // the child process ends 
} 

// This is a loop where the parent reads what the children sent 
for (int i = 0; i < pipes_count; i++) { 
    pipe_bytes = read(pipes[i][0], pipe_buffer, sizeof pipe_buffer); 
    if (pipe_bytes == 0) { 
     close(pipes[i][0]); 
    } else { 
     printf("Testing: %s\n", pipe_buffer); 
    } 
} 
+0

C에서'pipes [pipes_count] = new_pipefd;'와 같은 배열 할당을 할 수 없습니다.'fork()'의 반환 값을 검사하여 코드가 부모인지 자식인지를 알아야합니다. 표시된 코드를 통해 우리는 자신이 실제로 무엇인지를 알 수 없습니다. 루프에 대한 언급이 있지만 실제로 당신이하는 일이 중요합니다. 자식 프로세스는 분명히 자식 코드를 수행 한 후에 부모 코드를 실행하게됩니다. 실제 코드를 더 게시하십시오 - 잘못 될 수있는 많은 것들이 있으므로 어떤 문제가 있는지 추측하기가 어렵습니다. –

+0

그러면 어떻게 파이프 배열 (파일 기술자)을 얻을 수 있습니까? 이 포스트에서'fork()'리턴 값을 검사하는 코드를 제거했다. 주석을 더 분명하게해야했다. 부모와 자식에서 코드를 실행하면 실제 소스에서 제대로 작동합니다. 편집 : 편집을 보았습니다. 나는 돌아가서 모든 것을 더 분명하게하려고 노력할 것이다. – John

+0

나는 그것을 되 찾는다. 당신의'pipes'는'int'가 아닌'int *'배열입니다. 내 잘못이야. 그러나, 코드는'new_pipefd' 포인터를 배열의 각 위치에 복사하는 것으로 보이는데, 이것은별로 도움이되지 않습니다. 다른 값을 저장할 수 있어야합니다. 모든 코드를 표시하지 않았으므로이 권한이 있는지 여부는 알 수 없지만 표시하지는 않았습니다. 그것의 얼굴에, 모든 것이 마지막 아이에게서 독서이기 위하여려고하고있다. 파이프의 쓰기 끝을 닫으려면 부모 프로세스가 필요합니다. 사실, 일반적으로, 파이핑 (piping)과 함께, 많은 문제는 충분한 파일 기술자를 닫지 않기 때문에 발생합니다. –

답변

2

, 문제가에 할당 pipes[pipes_count] = new_pipefd;에 있습니다

int pipes_count = 0; 
int *pipes[MAXCLIENTS]; 
int new_pipefd[2]; 
int pipe_bytes; 
char pipe_buffer[MAXDATASIZE]; 

while(1) { 
    // Pipe creation 
    pipe(new_pipefd); 
    pipes[pipes_count] = new_pipefd; 
    pipes_count++; 

말썽 변수 new_pipefd가 배열이라는 것이다, 따라서 동일한 배열의 주소를 pipes의 각 요소에 복사합니다. 즉, 부모는 만든 마지막 파이프에만 액세스 할 수 있습니다.

난 당신이 더 같은 코드를 사용해야한다고 생각 :

int pipes_count = 0; 
int pipes[MAXCLIENTS]; // Changed type! 
int new_pipefd[2]; 
char pipe_buffer[MAXDATASIZE]; 

while (1) 
{ 
    // Pipe creation 
    pipe(new_pipefd); 
    pipes[pipes_count++] = new_pipefd[0]; // Just the read end of the pipe 

    if (fork()) 
    { 
     // unrelated code for parent here 
     close(new_pipefd[1]); // close the parent's write-end of the pipe 
     // break;    // This break is not wanted 
    } 
    else 
    { 
     // unrelated code for child here 
     close(new_pipefd[0]); // close the child's read-end of the pipe 
     break; 
    } 

    if (some condition) 
     break;  // The parent will stop creating pipes 
} 

while (condition that guarantees this is the child) 
{ 
    write(new_pipefd[1], buffer, strlen(recv_buffer)); 
    close(new_pipefd[1]); 
    return 0; // the child process ends 
} 

// This is a loop where the parent reads what the children sent 
for (int i = 0; i < pipes_count; i++) { 
    int pipe_bytes = read(pipes[i], pipe_buffer, sizeof(pipe_buffer)); 
    if (pipe_bytes != 0) 
     printf("Testing: %.*s\n", pipe_bytes, pipe_buffer); // Safe! 
    close(pipes[i]); 
} 

는 내 코드 있었, 나는에 호출 (I 전통적 be_childish() 전화) 기능을 가지고하려는 '그것은 아이가' 루프의 코드 블록 이 함수는 절대로 반환되지 않으며 필요한 리소스가 모두 전달됩니다 ( new_pipefd, 아마도 다른 정보도 가능). 나는 종종 부모님의 활동을하기 위해 be_parental()의 기능을 가지고있다. 이 코드는 대부분의 코드를 정리하여 작업을 명확하게 분리합니다.

+0

고마워요 조나단 !! – John

관련 문제