2012-11-07 5 views
1

저는 검색해서 아무 쓸모가 없으므로 마침내 도움을 요청했습니다. 저의 임무는 RedHat Linux에서 실행되는 C에서 두 개의 자식 프로세스를 생성하는데, 각 자식 프로세스는 임의의 양의 반복에 대한 문자를 파이프에 씁니다. 이 파이프는이를 생성 한 상위 프로세스와 공유됩니다. 아이들은 파이프에 글자를 쓸 때 파이프에서 읽습니다. 자식이 종료되고 파이프가 비어 있으면 부모 (주)가 종료 될 수 있습니다.2 명의 자녀가 파이프에 쓰고 부모가 C 파이프의 파이프에서 읽습니다.

여기에 제가 작성한 코드의 논리에 대한 빠른 & 더러운 예가 있습니다.

main() 
{ 
     //create pipe 

     fork(); //childA 
     //writes to pipe 

     fork(); //childB 
     //writes to pipe 

     //parent reading 
     while(condition) { 
      //read from pipe + print chars to terminal 
     } 
} 

이제 내 질문은 while 루프의 조건에 관한 것입니다. 아이들이 풀 파이프로 인해 글쓰기가 차단되었을 때 나는 읽을 필요가 있지만, 어떤 종류의 조건으로 이것을 할 수 있는지 알 수 없습니다. 어떤 도움이라도 절대적으로 훌륭합니다.

+0

항상 "전체 파이프"상태에서 벗어날 수있는 유일한 방법입니다. 마지막 자식이 파이프를 닫으면 read는 -1을 반환합니다. – wildplasser

+0

@wildplasser'read'는 파일의 끝에 0을, 에러시 -1을 반환합니다; 마지막 자식이 파이프를 닫고 읽을 데이터가 남아 있지 않으면 0을 반환합니다. 'fread'는 요청한 객체의 수 (또는 0)보다 작은 값을 반환하며, 파일의 끝이나 오류가 있는지를 결정하기 위해'feof'와'ferror'를 사용해야합니다. –

답변

0

읽을 때 파이프가 가득 찰 필요가 있습니까? 또는 파이프 중 하나가 가득 차서 자녀가 글쓰기를 할 수 없어도 두 자녀 모두에게 계속해서 읽는 것이 요구되는 것입니까?

파이프가 가득 차면 높이를 측정하는 표준 방법에 대해 모르겠다. FIONREAD ioctl을 사용하여 파이프에서 읽어야 할 데이터의 양을 확인하고 그 값을 PIPE_BUF과 비교해 볼 수는 있지만 파이프에 PIPE_BUF 데이터가 없지만 자식이 쓰기를 수행하면 제대로 작동하지 않을 수 있습니다 그것은 그것을 PIPE_BUF에 붙일 것이다; 그 호출은 파이프를 채우지 않고 막을 수 있습니다. 나는이 기술의 사용에 의존하지 않을 것이다.

두 파일 설명자를 읽을 준비가되어있는 관계없이 일반적인 방법은 select 시스템 호출을 사용하는 것입니다. 이렇게하면 하나 또는 다른 파일 설명자가 사용 가능한 데이터를 가질 때까지 기다릴 수 있습니다. 즉, 부모 프로세스는 사용 가능한 데이터가없는 한 자식을 읽는 것을 차단하지 않으며 다른 자식은 버퍼가 꽉 찼기 때문에 차단하고 있음을 의미합니다.

편집 : 질문을 다시 읽은 후에 실제로 두 파이프 모두 하나의 파이프 만있는 것처럼 들립니다. 그 맞습니까? 다시 말하면, 아이들이 막을 때까지 기다릴 필요가 있는지에 대한 질문이옵니다. 부모가 파이프에서 읽는 경우, 자식 중 하나가 파이프에 쓸 때까지 차단됩니다. 특별한 일을 할 필요가 없습니다.

파이프가 실제로 채워질 때까지 기다려야하는 과제가있는 경우 정확한 말씨를보고 싶습니다. 그 이유는 확실하지 않을 수 있습니다.

편집 2 : 주석의 질문에 대한 응답 :

  1. 내 부모 프로세스의 코드가 프로그램 내에서 내 두 자식 프로세스에 대한 코드를 따라야합니까?

    아니요, 아니요, 상위 또는 하위 프로세스의 코드 순서에 대한 요구 사항은 없습니다. 자식이 실행하는 코드에서 부모가 실행하는 코드를 구별하려면 반환 값 fork()을 확인합니다. 반환 값이 0이면 자식 프로세스에있는 것입니다. 그것이 아니라면, 당신은 부모입니다. 반환 값이 -1이면 오류가 발생하고 양수이면 오류가 자식 프로세스의 PID입니다.두 아이들이 종료 될 때까지 내가 파이프에서 읽기 유지할 수 있습니다 방법

    int pid = fork(); 
    if (pid == 0) { 
        // in the child, do whatever you need to do and... 
        exit(0); 
    } 
    
    // in the parent; since the child calls exit() above, control will never 
    // reach here in the child. Or you could do an execl() in the child, which 
    // replaces the current program with another one, so again, control will 
    // never reach here within the child process. 
    
  2. 및 파이프가 비어 있습니다 :

    int pid = fork(); 
    if (pid) { 
        // in the parent, check if pid is -1 for errors 
    } else { 
        // in the child 
    } 
    

    또는 :

    그래서, 당신은이 같은 코드를 작성할 수 있습니다 ?

    그냥 모든 프로세스가 파이프의 쓰기 끝을 닫을 때까지 read 리턴 파이프의 읽기 끝에 0 read 0을 반환하지 않습니다 때까지 계속 읽고, 모든 데이터는 파이프에서 읽을 수있다. 어떤 것이 아직 열렸지 만 파이프에 데이터가없는 경우 read은 데이터가 파이프에 기록 될 때까지 차단합니다.

    하나의 문제는 read을 시도하기 전에 상위 프로세스에서 파이프의 쓰기 끝을 닫는 것을 기억하는 것입니다. 그렇지 않으면 부모가 자식이 완료된 후 read을 수행하려고하면 자식이 자신의 파이프를 닫는 것을 기다리는 것을 차단합니다.

+0

실제로 두 어린이가 모두 쓰고 있고 부모가 읽고있는 파이프가 하나뿐입니다. 글쎄, 할당 상태의 요구 사항은 부모가 읽을 때마다 파이프에서 100자를 읽은 다음 해당 문자를 터미널에 인쇄합니다. 이 작업은 각 자식이 각 iterations (childA = 900 iterations, childB = 260 iterations)를 반복 할 때까지 수행됩니다. 아이들이 차단 될 때까지 기다릴 필요는 없지만 각 읽음마다 파이프에서 100자를 읽어야합니다. – user1807614

+0

내 주요 질문은 다음과 같습니다. 1. 부모 프로세스 코드가 프로그램 내 두 자식 프로세스 코드를 따라야합니까? 2. 두 자녀가 끝나고 파이프가 비어있을 때까지 파이프에서 계속 읽을 수 있습니까? – user1807614

+0

@ user1807614 내 대답에 귀하의 질문에 답변했습니다. –

관련 문제