IPC를 이용한 pipe에서...(코드 추가;)
글쓴이: cmak / 작성시간: 금, 2003/12/05 - 12:18오전
한 번에 3개의 프로세스, 즉
cmd1 | cmd2 | cmd3
와 같은 결과를 얻어내는 함수를 만들려고 하는데요.
앞 부분의 프로세스에서 얻은 결과를 다음 프로세스의 파이프 입력에 넣어주고자 다음과 같은 방식으로 코딩을 했습니다.
int p[2][2]; pipe(p[0]); pipe(p[1]); // 파이프 2개 설정 switch(fork()){ case 0: switch(fork()){ case 0: close(p[0][0]); close(p[1][0]); close(p[1][1]); dup2(p[0][1], 1); close(p[0][1]); execvp(cmd1[0], cmd1); //첫 번째 프로세스 exit(1); default: wait((int *)0); } dup2(p[0][0], 0); dup2(p[1][1], 1); close(p[0][0]); close(p[0][1]); close(p[1][0]); close(p[1][1]); execvp(cmd2[0], cmd2); //두 번째 프로세스 exit(1); default: wait((int *)0); close(p[0][0]); close(p[0][1]); dup2(p[1][0], 0); close(p[1][0]); close(p[1][1]); execvp(cmd3[0], cmd3); //세 번째 프로세스 exit(1); } }
그런데 실행해 보면, 상호간에 값을 제대로 못받습니다.
2개만 할 때는 위의 코드에서
dup2(p[1], 1); ... //첫 번째 프로세스 dup2(p[0], 0); ...// 두 번째 프로세스
로 변형된 형태의 방식을 이용했었는데 잘 되었었습니다.
도데체 왜 이런 일이 일어나는 건지요....;;
Forums:
상당히 모호한 질문이네요.
제가 보기에 질문한 내용에 대한 답변은 fork에 대한 내용인 것 같은데, 질문 내용에는 fork 관련 코드를 모두 제거한 상황이네요. 이런 경우 답변을 달기 상당히 곤란합니다.
현재의 핵심은 fork에 있느니, fork 코드를 집어 넣는 것이 답변을 얻는 지름길입니다.
그리고.. 제가 머리 속의 개념으로 답변을 하면.
1)
pid -> ppid1, ppid2 -> id1, id2, id3, id4
2)
pid -> ppid1 -> pppid 1, pppid2
\_ ppid2 -> ???
pid(프로세스 아이디) 에서 파생하는 자식들을 그래프로 그려서
몇 개의 자식 프로세스가 생성되는 지를 알아보는 것이 아마 문제의 해결점이 되지 않을 까 생각됩니다.
현재 생각하는 것과 코드의 구현과는 다를 수 있으니, 손으로 한 번 그려 보는 것이 머리속에서 그려 보는 것 보다 나은 결과를 가져올 수 있습니다.
이만.
berise@nowhere.comes.out
..
결국 dup2()한 것이 execvp로 생성된 프로세스에 영향을 못준다는
것 같네요.. 프로세스 2개로만 할때는 dup2()로 인한것보다는
단순히 stdout, stdin에 썼기 때문에 두 프로세스간에 통신이 된것
같구요..
dup2() call을 쓰기 보다 pipe의 fd를 parameter로 넘기는 방법을
써보심이 어떨지?
11
제가 새로운 버전의 fork() 함수를 만들어 봤습니다.
방금 대충 만든거라서 오류가 잇을지도..
파이프는 그림을 그리면서 하는 것이 좋을것 같습니다.
아래의 pipe_connected_fork() 함수는
자식을 하나 생성하고 부모의 표준 출력을 자식의
표준입력으로 연결시켜놓는 기능을 합니다.
그니깐 파이프로 연결된 자식을 만드는 것이죠
아마도 쉘을 만드시는듯..
만약 a.out | b.out | c.out | d.out | e.out
이런식으로 파이프가 엄청길다면
님처럼 파이프 배열로 한다면 햇갈릴것 같습니다.
pipd_connected_fork()함수를 쓰면 편리할 것 같은데요
예제 코드입니다.
이렇식으로 호출하면......... 되겠죠?
(안될지도 모르겟군요..^^;;
암튼 함수단위로 생각하시면 더 편리할듯..)
..
2개의 파이프를 만들 필요가 없다고 생각합니다.
생각해 보니 부모 프로세스에서는
파이프를 하나만 만들면 충분할 것 같습니다.
자식과 연결하는 파이프를 부모가 만드는 겁니다
예를 들어 A, B ,C 라는 프로세스가 있을 때
(A가 최상위 parent , 순차적으로 chlid.)
A는 자식 프로세스 B를 위해 하나의 파이프 만을 만들면 됩니다.
B는 A로 부터 파이프를 물려받고,
만약 C라는 child를 만들고 싶다면 B가 파이프를 "하나" 만든후에
fork()하면 됩니다.
이런 식으로 재귀적으로 fork()와 pipe생성이 일어나는 것이
구조적으로 좋아 보입니다.
ps.결과적으로는 최상위 parent와 최하위 child를 제외한 모든 프로세스는
2개의 파이프를 갖는 결과가 나타날 것입니다.
댓글 달기