fork(); 프로그램에서...
글쓴이: 불량청년 / 작성시간: 월, 2002/12/30 - 3:31오후
다름이 아니오라, fork();함수 사용에서 의문점이 있어서 그러는데요.
아래 간단한 소스를 컴파일 시키고 리다이렉트 시키면 결과과 다르게
나오는데 왜 이러는지요?
#include <unistd.h> #include <sys/types.h> int global = 6; char buf[] = "write to stdout\n"; int main(void) { int var; pid_t pid; var = 55; if(write(STDOUT_FILENO, buf, sizeof(buf)-1) != sizeof(buf)-1) perror("write error"); printf("before fork\n"); if((pid = fork()) < 0) perror("fork error"); else if(pid == 0){ global++; var++; }else{ sleep(3); } printf("pid = %d, global = %d, var = %d\n", getpid(), global, var); exit(0); }
$ a.out
write to stdout
before fork
pid = 450, global = 6, var = 56
pid = 449, global = 5, var = 55
그냥 실행시 이렇게 나오는데...
$ a.out > temp.out
$ more temp.out
write to stdout
before fork
pid = 450, global = 6, var = 56
before fork
pid = 449, global = 5, var = 55
"before fork"라는 내용이 두번 저렇게 나오는데... 왜그런거죠?
fork(); 호출전에 출력했던 내용이 다시 나오는거 같은데...
Forums:
음... 예전에 이 현상에 대해서 설명을 들어는데 확실히 기억이 안나네요
음... 예전에 이 현상에 대해서 설명을 들어는데 확실히 기억이 안나네요..
기억나는 대로 말씀 드리자면...
printf()는 바로 출력을 하는 것이 아니라 buffer에 내용을 담아 두었다가
내용을 출력합니다.
그런데 이넘의 버퍼가 비워지는 시점이 fork() 전 일 경우에는 정상적으로
1번만 출력이 됩니다만...
버퍼가 비워지기 전에 forkr()가 호출되면 버퍼의 내용까지 같이 복사가 됩니다.
따라서 후에 버퍼가 비워질때 앞서 출력되지 않은 내용이 같이 출력 되게 되므로
부모와 자식 모두에서 1번씩 출력이 되게 됩니다.
==
흠... 제가 아는건 이정돈데... 자세하게는 몰겠네요... 그럼...
그런데요...
일반적으로 write();시스템 콜은 표준I/O 라이브러리를 안쓰므로
버퍼링을 하지 않는 걸로 알고 있거든요. 고로, write(); 호출시
바로 출력되지 않는지요?
제가 만약 write(); 대신에 fputs나 기타 다른 버퍼링을 지원하는
입출력 라이브러리 함수를 사용했다면 이해가 가겠는데...
아~ 스티븐스 아저씨 책에 나오긴 나왔는데 이해가 안가네요.
혹시 write(); 호출시 데이터가 커널 버퍼에서 잠시 남아 있다가
fork(); 호출시 님 말대로 같이 데이터 영역이 복사되어서 두번 호출
되는것이 아닐런지요? :?
만약, printf(); 호출 말고 스트림 출력 함수를 쓴 후에 fflush(); 하면
저런 현상은 안나올껏도 같은데...
write(); 시스템콜에 대한 이해가 필요할꺼 같군요. ㅜㅜ;
답변 감사합니다.
H/W가 컴퓨터의 심장이라면 S/W는 컴퓨터의 영혼이다!
알겠습니다.
제가 책을 제대로 안봤네요. ㅜㅜ;
터미널로 리다이렉트 시키면 당연히 라인버퍼링이 되네요.
고로 저런 현상이 나타날 수 밖에 없구요. ㅡㅡ;
H/W가 컴퓨터의 심장이라면 S/W는 컴퓨터의 영혼이다!
네. fflush() 써 주셔야 합니다. :)
네. fflush() 써 주셔야 합니다. :)
"I conduct to live,
I live to compose."
--- Gustav Mahler
댓글 달기