저는 한 아이의 출력을 다른 아이의 입력으로 연결하는 임무를 맡은 테스트를 수행하고 있습니다. ps -ef
첫 번째 명령을 사용하고 있습니다 ( execlp())
및 grep root
두 번째 명령으로 사용(bu 사용 execlp()
). 원하는 출력을 얻고 있지만 grep을 실행하는 과정에서 차단됩니다. 현재 실행 중인지 확인하기 위해 top 명령을 사용했습니다. 프로세스.
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<fcntl.h>
int main(){
int status,i;
int fds[2];
pid_t pid;
//pid=fork();;
if(pipe(fds)==-1){
perror("Error:");
exit(0);
}
if(fork()>0){
printf("The pid of the parent is %d\n",getpid());
if(fork()==0){
printf("The PID of the 2nd child %d\n",getpid());
//printf("Inside 2nd child\n");
close(0);
dup(fds[0]);
close(fds[1]);
//fcntl(fds[0],F_SETFD,FD_CLOEXEC);
//printf("The PID of the 2nd child %d\n",getpid());
if(execlp("grep","grep","root",NULL)==-1){
perror("ERROR FROM SECOND CHILD: ");
exit(1);
}
}
else{
printf("The parent is waiting\n");
/*for(i=0;i<2;i++){
printf("%d The PID OF THE EXIT CHILD is %d\n",i,wait(&status));
}*/
while(wait(NULL)>0)
perror("Error From Main:\n");
//wait(&status);
printf("The parent exited from the waiting stage\n");
return 0;
}
//while(1);
}
else{
close(1);
dup(fds[1]);
close(fds[0]);
//close(1);
printf("The pid of the First child is %d\n",getpid());
if(execlp("ps","ps","-ef",NULL)==-1){
perror("Error:");
exit(1);
}
}
}
도와주세요. 제가 껍질을 만들고 있으니까요. 이 작업을 수행하는 것이 필요합니다.
답변1
파이프의 다른 쓰기 측에서 EOF를 얻지 못하기 때문에 grep 프로세스가 차단됩니다. 연관된 쓰기 파일(fds[1]) 설명자가 닫힐 때 EOF가 판독기 측으로 전송됩니다. 내 실수는 파이프에 쓰는 프로세스에서 쓰기 설명자(fds[1])를 닫았음에도 불구하고 상위 프로세스(main)에서 쓰기 설명자(fds[1])를 닫지 않았다는 것입니다.
따라서 다음과 같은 질문이 생길 수 있습니다. 설명자를 사용하지 않더라도 설명자를 닫아야 합니까? 예 예! 상위 프로세스와 하위 프로세스에는 동일한 설명자 복사본이 있기 때문에 이러한 설명자는 기본적으로 메모리 참조입니다(잘 모르겠습니다). 따라서 한 프로세스에서 닫히더라도 다른 프로세스에서 다른 복사본이 열릴 수 있으며, 이로 인해 파이프에서 데이터를 읽는 세 번째 프로세스가 차단될 수 있습니다.
파일 설명자를 조사하기 위해 cat /proc//를 사용하여 디버깅했습니다.