IPC를 이용한 pipe에서...(코드 추가;)

cmak의 이미지

한 번에 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);

...// 두 번째 프로세스

로 변형된 형태의 방식을 이용했었는데 잘 되었었습니다.

도데체 왜 이런 일이 일어나는 건지요....;;

berise의 이미지

제가 보기에 질문한 내용에 대한 답변은 fork에 대한 내용인 것 같은데, 질문 내용에는 fork 관련 코드를 모두 제거한 상황이네요. 이런 경우 답변을 달기 상당히 곤란합니다.

현재의 핵심은 fork에 있느니, fork 코드를 집어 넣는 것이 답변을 얻는 지름길입니다.

그리고.. 제가 머리 속의 개념으로 답변을 하면.

1)
pid -> ppid1, ppid2 -> id1, id2, id3, id4

2)
pid -> ppid1 -> pppid 1, pppid2
\_ ppid2 -> ???

pid(프로세스 아이디) 에서 파생하는 자식들을 그래프로 그려서
몇 개의 자식 프로세스가 생성되는 지를 알아보는 것이 아마 문제의 해결점이 되지 않을 까 생각됩니다.

현재 생각하는 것과 코드의 구현과는 다를 수 있으니, 손으로 한 번 그려 보는 것이 머리속에서 그려 보는 것 보다 나은 결과를 가져올 수 있습니다.

이만.

moonzoo의 이미지

결국 dup2()한 것이 execvp로 생성된 프로세스에 영향을 못준다는

것 같네요.. 프로세스 2개로만 할때는 dup2()로 인한것보다는

단순히 stdout, stdin에 썼기 때문에 두 프로세스간에 통신이 된것

같구요..

dup2() call을 쓰기 보다 pipe의 fd를 parameter로 넘기는 방법을

써보심이 어떨지?

bw001730의 이미지

제가 새로운 버전의 fork() 함수를 만들어 봤습니다.
방금 대충 만든거라서 오류가 잇을지도..
파이프는 그림을 그리면서 하는 것이 좋을것 같습니다.
아래의 pipe_connected_fork() 함수는
자식을 하나 생성하고 부모의 표준 출력을 자식의
표준입력으로 연결시켜놓는 기능을 합니다.
그니깐 파이프로 연결된 자식을 만드는 것이죠

아마도 쉘을 만드시는듯..
만약 a.out | b.out | c.out | d.out | e.out
이런식으로 파이프가 엄청길다면
님처럼 파이프 배열로 한다면 햇갈릴것 같습니다.
pipd_connected_fork()함수를 쓰면 편리할 것 같은데요


pid_t  pipe_connected_fork()
{
       pid_t pid;
       int   pf[2];
       pipe(pf);
       
       pid = fork();
       if( pid > 0) // 부모
       {
       		dup2( pf[1],1);
       		close(pf[0]);
       		close(pf[1]);       		
       		return pid;
       }
       else if( pid == 0)
       {
       		dup2(pf[0],0);
       		close(pf[1]);
       		close(pf[0]);
       }
       return pid;
}

예제 코드입니다.

main()
{
	char  *cmd;
	command_array[0] = "cmd0";
	command_array[1] = "cmd1";
	command_array[2] = "cmd2";
	for( i=0;  i<ncommand  ; i++)
	{
		if (pipe_connected_fork() > 0)
		{
			execvp( command_array[i] );
			break;
		}	
		// 자식은 continue
	}
}

이렇식으로 호출하면......... 되겠죠?
(안될지도 모르겟군요..^^;;
암튼 함수단위로 생각하시면 더 편리할듯..)

moonzoo의 이미지

2개의 파이프를 만들 필요가 없다고 생각합니다.

생각해 보니 부모 프로세스에서는

파이프를 하나만 만들면 충분할 것 같습니다.

자식과 연결하는 파이프를 부모가 만드는 겁니다

예를 들어 A, B ,C 라는 프로세스가 있을 때
(A가 최상위 parent , 순차적으로 chlid.)

A는 자식 프로세스 B를 위해 하나의 파이프 만을 만들면 됩니다.

B는 A로 부터 파이프를 물려받고,

만약 C라는 child를 만들고 싶다면 B가 파이프를 "하나" 만든후에

fork()하면 됩니다.

이런 식으로 재귀적으로 fork()와 pipe생성이 일어나는 것이

구조적으로 좋아 보입니다.

ps.결과적으로는 최상위 parent와 최하위 child를 제외한 모든 프로세스는

2개의 파이프를 갖는 결과가 나타날 것입니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.