-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- | about buffering | =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= | id: hkpco | | mail&msn: hkpco@korea.com | | homepage: http://hkpco.kr/ | -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- // printf() 등의 출력 함수를 사용할 때 문자열이 즉시 출력되지 않는 경우가 바로 버퍼링 때문입니다. 그에대해 쓴 글입니다. 출력문을 사용하였을때 바로 화면에 출력되지 않는 상태를 버퍼링 또는 일시저장 이라고 합니다. 출력문에서 개행문자 따위가 없다면 버퍼에 저장된 뒤 나중에 출력됩니다. 아래는 그 이유 * 일시저장(버퍼링)의 목적: read()와 write()함수 호출의 최소화. 일시저장(버퍼링)의 종류는 fully buffered line buffered unbuffered 가 있습니다. (완전일시저장) (줄 일시저장) (비 일시저장) 먼저 완전 일시저장의 경우에는 버퍼의 공간이 다 채워졌을때나 fflush()와 같은 함수들을 통하여 버퍼가 수동으로 비워지면서 stdout(표준 파일디스크립터)에 출력됩니다. 즉, 일시저장은 printf(), scanf() 따위의 함수 내부에서 동작하는 read()와 write()의 호출을 최소화 하기 위해서 잠시 버퍼라는 공간에 저장되었다가(\n를 사용한 경우는 제외) 버퍼가 다 차거나, fflush()를 사용하거나, 시간이 지나면 자동으로 비워지게(버퍼가 비워진다는 말은 출력을 의미) 됩니다. ~줄 일시저장(Line buffered) 경우에는 \n 을 만났을때 버퍼를 비웁니다. 또, 입력이 요구될때 마다(scanf등의 함수 호출) 버퍼를 비웁니다. ~비 일시저장(Unbuffered)은 표준에러로 문자열이 출력될때는 버퍼링 되지 않고 바로 화면에 출력됩니다. 이것은 되도록 빨리 에러가 보여질수 있도록 하기 위함입니다. 만약 버퍼링을 원치 않는다면 setbuf() 함수나 setvbuf() 함수를 사용합니다. #include void setbuf( FILE *fp , char *buf ); int setvbuf( FILE *fp , char *buf , int mode , size_t size ); 아래 두 코드를 직접 실행/비교 해보는것도 눈으로 확인할 수 있는 좋은 방법입니다. /* stdout_p.c */ #include int main( void ) { int i=0; for( ; i<=99999 ; i++ ) { fprintf( stdout , "%d\r" , i ); // stdout print sleep(1); } printf( "\n" ); } /* stderr_p.c */ #include int main( void ) { int i=0; for( ; i<=99999 ; i++ ) { fprintf( stderr , "%d\r" , i ); // stderr print sleep(1); } printf( "\n" ); } 말했듯이, 표준에러는 바로 출력된다고 하였습니다. 그래서 stderr_p.c는 컴파일 뒤 실행시켜 보면 출력이 즉각즉각 되지만 stdout_p.c는 버퍼가 다 차기 전 까지는 출력되지 않습니다. 이런식으로 예제를 사용하여 확인해 보는것도 좋은 방법입니다. End Of Document