2014-09-24 4 views
1

저는 C로 파이프를 사용하는 법을 배우고 있으며, 자식 프로세스의 파이프에 하나씩 문자열 목록을 쓰는 데 어려움을 겪고 있습니다. 그런 다음 상위 프로세스의 파이프에서이를 읽습니다. 여기에 내 현재 코드 :파이프를 사용하여 C 배열로 문자열 읽기 C

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

int main() 
{ 
    int pfd[2]; 
    char buf[1000]; 
    int cfork; 

    if (pipe(pfd) == -1) { 
     exit(1); 
    } 

    cfork = fork(); 

    if (cfork == -1) { 
     printf("Fork Failed\n"); 
     exit(1); 
    } 
    else if (cfork == 0) { 
     printf("Child Process\n"); 

     char *fruit[] = { 
      "Orange", "Apple", 
      "Banana", "Pear" 
     }; 

     int num_fruit = 4; 
     for (int i = 0; i < num_fruit; i++) { 
      printf("Current fruit: %s\n", fruit[i]); 
      write(pfd[1], fruit[i], (strlen(fruit[i]))); 
     } 
     _exit(0); 
    } 
    else { 
     printf("Parent Process\n"); 
     read(pfd[0], buf, sizeof(buf)); 
     printf("Fruit Fetched: %s\n", buf); 
     wait(NULL); 
    } 

    return 0; 

} 

내가 뭘하려고 오전, 아이에가, 과일 문자열을 읽어 파이프에 기록하고, 부모가 그것을이 문자열을 읽고 인쇄가, 때까지 모든 문자열이 인쇄되었습니다. 내 문제는 자식이 루프에 있기 때문에 각 문자열을 버퍼에 계속 추가하기 때문에 프로그램은 "OrangeAppleBanana"를 인쇄합니다. 나는 부모에게도 루프가 필요할 것이라고 확신하지만, 자식에 의해 보내지는 (예를 들어 "done") 어떤 끝 조건 문자열을 기다리는 while 루프를 시도했을 때, 내 프로그램은 여전히 무한 루프.

C를 처음 사용하는 사람이 아이에게 1 바이트 씩 문자열을 쓰고 부모 프로세스가 1 바이트 씩 출력하도록하는 가장 쉬운 방법은 무엇입니까?

편집

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

int main() 
{ 
    int pfd[2]; 
    int cfork; 

    if (pipe(pfd) == -1) { 
     exit(1); 
    } 

    cfork = fork(); 

    if (cfork == -1) { 
     printf("Fork Failed\n"); 
     exit(1); 
    } 
    else if (cfork == 0) { 

     int numbers[] = { 
      1, 2, 
      3, 4 
     }; 

     int limit = 4; 
     close(pfd[0]); 
     for (int i = 0; i < limit; i++) { 
      printf("Child - Current Number: %d\n", numbers[i]); 
      write(pfd[1], &numbers[i], sizeof(numbers[i])); 
     } 
     close(pfd[1]); 
     _exit(0); 
    } 
    else { 

     int temp; 
     int reads = 4; 
     close(pfd[1]); 
     for (int i = 0; i < reads; i++) { 
      read(pfd[0], &temp, sizeof(temp)); 
      printf("Parent - Number Fetched: %d\n", temp); 
     } 
     close(pfd[0]); 
     waitpid(-1, NULL, 0); 
    } 

    return 0; 

이 내가 대신 문자열의 정수를 사용하여 내 새로운 코드입니다. 지금까지 작동하는 것 같습니다. 그래도 내가 문자열로 잘못하고 있는지 확실하지 않습니다.

답변

0
//Child 
close(pfd[0]); // Close read end this blocks if parent is reading from pipe 
write(pfd[1]...); // write data into pipe 
close(pfd[1]); // close write end of pipe now the pipe is ready to read 

// Parent 
close(pfd[1]); // close write end of pipe blocks if child is writing to pipe. 
read(pfd[0] ...); 
close(pfd[0]..); // close read end so pipe is ready to write to. 
1

나는 "문자열"에 문제가 있다고 생각합니다. C의 문자열은 null로 끝나기 때문에 파이프를 통해 보낼 때 수신자 (부모)는 문자열이 끝나는 위치를 알 수 없습니다. Strlen은 문자열의 문자 수를 계산하지만 널 문자는 계산하지 않습니다. 다음을해야합니다 :

write(pfd[1], fruit[i], (strlen(fruit[i]))+1); 

부모는 이제 언제 어디에서 문자열을 분할 할 수 있는지 알 수 있습니다.

다른 문제는 여러분도 parrent에서도 반복해야한다는 것입니다. 루프에서 EOF를 확인하는 조건을 설정해야합니다. 당신이 4 과일을 먹을 것이라는 것을 당신이 알고있는 당신의 예에서, 당신은 단지 4 번 반복 할 수 있습니다.

필요하지 않은 파이프의 읽기 및 쓰기 끝을 닫는 것이 좋습니다. 예를 들어, 자녀는 읽기 끝을 닫아야하며, 부모는 쓰기 끝을 닫아야합니다. 당신은 또한 당신이 필요로하지 않는 모든 기술자를 닫는에 익숙해한다

close(pfd[0]); //use this in child 

close(pfd[1]); //use this in parent 

: 당신은이 작업을 수행 할 수 있습니다. 예를 들어, 쓰기/읽기가 끝나면 자식 프로세스와 부모 프로세스 모두에서 파이프를 닫아야합니다. 이렇게하면 EOF 이후에 닫히는 읽기 루프 조건을 만들 수 있습니다. 추가 팁으로

을 (아이가 파이프를 닫을 때, 수신기가 끝날 수), 나는 각각의 루프 내부 또는 외부 닫기() 문을 놓아야합니다 "perror는" http://www.tutorialspoint.com/c_standard_library/c_function_perror.htm

+0

에 오류보고를 시도? 나는 당신이 제안한대로 strlen()을 바꿨고, 루프의 다른 루프를 파이프에서 읽고 루프를 만들었고 루프 외부에 close() 문을 둘 다 넣었다. 여전히 올바른 출력을 얻지 못합니다. 또한, 나는 부모님에게 wait() 또는 waitpid()를 추가해야한다면 혼란 스럽다. 루프에? 외부? 나는 둘 다 시도했지만, 나는 틀린 일을해야만한다. – SherMM

+0

저는 지금 집 컴퓨터가 아니므로 솔루션이 작동하는지 테스트 할 수 없습니다. 나는 집에 도착하자마자 곧 갈 것이다. 자식 프로세스에서 pfd [0]을 닫고 부모 프로세스에서 pfd [1]을 닫아야합니다. 루프를 닫지 않고 포크를 잡고 나면 한 번만 닫아야합니다.어떤 결과물을 얻고 있는지 말해 줄 수 있습니까? 아마도 새로운 루프를 작성하여 코드를 볼 수 있을까요? 나는 집에 돌아와서 직접 테스트 할 수있는 몇 시간 안에 해결책을 게시 할 것입니다. – IamSneaky

+0

지금 나와 같은 상황. 기회가 생기면 코드를 게시 할 것입니다. 원래 과일 목록 대신 정수 목록만으로 실행했습니다. 문자열이 읽히는 것과 관련이있을 수도 있습니다. – SherMM