1 #include "apue.h"
2
3 int glob = 6;
4 char buf[] = "a write to stdout\n";
5
6
7
8 int main()
9 {
10 int var;
11 pid_t pid;
12
13
14 var = 88;
15 if(write(STDOUT_FILENO, buf, sizeof(buf)-1) != sizeof(buf)-1)
16 err_sys("write error");
17
18 printf("before fork\n");
19
20 if((pid = fork()) < 0) {
21 err_sys("fork error");
22 }
23 else if(pid == 0) {
24 glob++;
25 var++;
26 }
27 else {
28 sleep(2);
29 }
30
31 printf("pid = %d, glob = %d, var = %d\n", getpid(), glob, var);
32 exit(0);
33 }
일단 간단한 소스코드 입니다.
./example
a write to stdout
before fork
pid = 32667, glob = 7, var = 89
pid = 32666, glob = 6, var = 88
출력결과입니다. 다들 예상하셨죠?
이제 파일로 재지향 해보겠습니다.
./example > test.txt
vi test.txt
1 a write to stdout
2 before fork
3 pid = 32706, glob = 7, var = 89
4 before fork
5 pid = 32705, glob = 6, var = 88
before fork 가 두번 출력되었습니다.
버퍼링 차이 때문입니다.
write 함수는 버퍼링이 되지 않습니다 바로 출력이 되지요
write 가 fork 보다 먼저 실행되니까 당연히 한번만 출력됩니다.
표준 I/O 라이브러리는 버퍼링이 되는걸로 알고 있습니다.
여기서 표준 출력이 터미널이면 라인 버퍼링을 합니다.
그래서 정상적으로 나왔고
재지향 하여 파일로 보내면 아직 printf로 호출한 이후 버퍼에 값이 남아있습니다.
버퍼링 된 걸 fork 로 하여 모두 자식한테 복사합니다.
그래서 부모와 자식의 버퍼가 같은 상태가 됩니다.
각 각의 프로세스 가 종료되면 해당 버퍼의 복사본이 최종적으로 방출됩니다.
그럼 해결방법도 알아야 겠죠?
표준 I/O 함수를 사용시 버퍼안에 내용을 지울려면 fflush(stdout) 을 사용하면 됩니다.
뭐 다들 아시는 기초적인 내용이지만 저 같이 머리가 나쁜 경우 꼭 까먹어서.. ㅋㅋ
history