3 개의 자식 프로세스 사이에 두 개의 파이프를 만들고 싶지만 먼저 pipe1
두 개의 포크 프로세스 사이에서 작동 하는 첫 번째 파이프를 얻고 싶습니다 . 문제는 내가 첫 번째 프로세스에서 stdout을 복제하고 마찬가지로 다른 프로세스에서 stdin을 복제하면 출력을 얻지 못한다는 것입니다.
int main()
{
int pipe1[2];
int pipe2[2];
pipe(pipe1);
pipe(pipe2);
sem_t mutex_pipe1;
sem_t mutex_pipe2;
sem_init(&mutex_pipe1, 0, 0);
sem_init(&mutex_pipe2, 0, 1);
if (fork()==0) { //process 1
close(1); /* close normal stdout */
dup(pipe1[1]); /* make stdout same as pfds[1] */
sem_post(&mutex_pipe1);
execlp("ls", "ls", NULL);
}
if (fork()==0){ //process 2
sem_wait(&mutex_pipe1);
close(0);
dup(pipe1[0]);
dup2(pipe1[1], 1) //want to open stdout again.
sem_post(&mutex_pipe1);
execlp("wc", "wc", "-l", NULL);
}
귀하의 세마포는 귀하가 제시 한 코드에서 유용한 작업을 수행하지 않습니다. 특히 자식 프로세스가 exec()
-family 함수를 호출하면 그들이 무엇을 할 수 있다고 생각하는지는 분명하지 않습니다 .
또한 일단 닫히면 "표준 출력을 다시 열 수"없습니다. 파일 설명자 1 (및 따라서 stdout
)을 다른 파일과 연결할 수 있지만, 파일을 다시 open()
실행하거나 fopen()
다시 실행하는 경우 를 제외하고는 연결된 모든 FD를 닫은 후에는 파일을 다시 가져올 수 없습니다 .
그러나 a 이후에 fork()
자식 및 부모 프로세스가 메모리를 공유하지 않는다는 점을 인식하지 못하는 것 같습니다 . 적어도 하나의 일반 메모리 쓰기가 다른 사람에게 표시된다는 의미에서는 아닙니다. 따라서 원래 코드에서 첫 번째 자식이를 닫을 때 stdout
부모는 영향을받지 않으며 두 번째 자식은 변경 사항이나 원본을 복구 할 필요가 없습니다 stdout
.
반면에 fork()
자식 프로세스가 부모의 열린 파일 설명자를 상속하면 해당 파일 설명자가 각각 열린 두 개의 프로세스가 생성된다는 점에 유의하십시오. 또한 FD를 복제하면 동일한 파일에서 두 번째 FD가 열립니다. 기본 열린 파일 을 닫기 전에 모든 파일을 닫아야하며 그렇지 않으면 원하지 않는 결과가 발생할 수 있습니다. 특히 귀하의 경우에는, 두 번째 자식 프로세스의 중단은 그것이 기다리고 있기 때문에 stdin
다른 측면에서 폐쇄하고, 첫 번째 자식 프로세스가 종료하지만 그 사본을, 부모 프로세스는 여전히에서 열린 FD를 보유하고 있습니다. wc
그것의 전체 입력을 소비 할 때까지 프로그램이 출력을 작성하지 않습니다. 대신 실행하는 경우 일부 출력을 볼 수 있습니다.cat
.
또한 부모는 일반적으로 자신을 종료하기 전에 자식 프로세스가 완료 될 때까지 기다려야하며, 다른 작업을 계속 수행하면 결국에는 프로세스가 정리 될 때까지 기다려야합니다.
마지막으로, 항상, 항상 에러 코드 반환 값을 확인합니다.
다음은 파이프를 통해 단방향으로 통신하는 한 쌍의 자식 프로세스를 설정하는 방법에 대한 아주 최소한의 버전입니다.
#define DIE do { perror(NULL); exit(1); } while (0)
#define DO_OR_DIE(f) do { if ((f) < 0) DIE; } while (0)
int main(void)
{
int pipe1[2];
DO_OR_DIE(pipe(pipe1));
switch (fork()) {
case -1: /* failed to fork */
DIE;
case 0: /* child process 1 */
/* make stdout a copy of the write end of the pipe */
DO_OR_DIE(dup2(pipe1[1], STDOUT_FILENO));
/* close the excess file descriptor */
DO_OR_DIE(close(pipe1[1]));
execlp("ls", "ls", NULL);
/* execlp returns only on failure */
DIE;
/* default: parent process */
}
/* close the parent's copy of this FD, lest child2 hang */
DO_OR_DIE(close(pipe1[1]));
switch (fork()) {
case -1: /* failed to fork */
DIE;
case 0: /* child process 1 */
/* make stdout a copy of the write end of the pipe */
DO_OR_DIE(dup2(pipe1[0], STDIN_FILENO));
/* close the excess file descriptor */
DO_OR_DIE(close(pipe1[0]));
execlp("wc", "wc", "-l", NULL);
/* execlp returns only on failure */
DIE;
/* default: parent process */
}
/* close the parent's copy of this FD, for consistency and tidiness*/
DO_OR_DIE(close(pipe1[0]));
/* wait for two child processes to stop */
DO_OR_DIE(wait(NULL));
DO_OR_DIE(wait(NULL));
return 0;
}
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다