_IO_SYSWRITE , _IO_SYSREAD , _IO_overflow , _IO_underflow , _IO_flush diff
기본적인 글
항상 헷갈리는 얘들이러서 그냥 이참에 깔끔히 정리 하려한다.
| 함수 | 언제 호출되나요? | 무슨 일을 하나요? (무엇을 호출?) |
|---|---|---|
| _IO_write | _IO_overflow 나 _IO_flush 가 시킬 때 | 커널 write() 호출 (데이터 쓰기) |
| _IO_read | _IO_underflow 가 시킬 때 | 커널 read() 호출 (데이터 읽기) |
| _IO_overflow(FILE *f, int ch) | 출력 버퍼가 꽉 찼을 때 / exit() 때 | _IO_write 를 호출해 버퍼를 비움 → 그리고 ch를 첫번째 버퍼에 넣는다. |
| _IO_underflow | 입력 버퍼가 비었을 때 | _IO_read 를 호출해 버퍼를 채움 |
| _IO_flush | 얘는 사실 실제로 존재하는 기능이 아니고 _IO_overflow 내부에서 write를 하는 매크로임 | _IO_write 를 호출해 버퍼를 비움 |
참고로 _IO_overflow가 exit 때 호출이 되는 이유는 프로그램을 끝낼때 각각의 파일에 있는 버퍼를 모두 비우기 위함이다.
_IO_flush는 사실 가짜이다.
즉, 이름만 있을뿐 사실 _IO_overflow의 내부에서 존재하는 일부이며,
_IO_overflow(FP , EOF ) 처럼 EOF를 주면,
C
if (ch == EOF)
return _IO_do_write (f, f->_IO_write_base,
f->_IO_write_ptr - f->_IO_write_base);
if (f->_IO_write_ptr == f->_IO_buf_end ) /* Buffer is really full */
if (_IO_do_flush (f) == EOF)
return EOF;다음과 같이 _IO_overflow 함수 내에서 _IO_do_flush 가 실행되는 것처럼 보이지만,
C
#define _IO_do_flush(_f) \
((_f)->_mode <= 0 \
? _IO_do_write(_f, (_f)->_IO_write_base, \
(_f)->_IO_write_ptr-(_f)->_IO_write_base) \
: _IO_wdo_write(_f, (_f)->_wide_data->_IO_write_base, \
((_f)->_wide_data->_IO_write_ptr \
- (_f)->_wide_data->_IO_write_base)))이는 write를 하는 매크로이다.
우리가 fflush() 이런식으로 함수를 사용해도,
C
int
_IO_fflush (FILE *fp)
{
if (fp == NULL)
return _IO_flush_all ();
else
{
int result;
CHECK_FILE (fp, EOF);
_IO_acquire_lock (fp);
result = _IO_SYNC (fp) ? EOF : 0;
_IO_release_lock (fp);
return result;
}
}_IO_flush_all 가 실행되고
_IO_flush_all → _IO_flush_all_lockp 을 거친뒤에 결국
C
_IO_OVERFLOW (fp, EOF) == EOF)가 실행이 된다.
즉, 모든 버퍼의 내보내기는 overflow에서 관리를 하며, 평소에는 가득찼을때 소환이 되지만, 안차도 강제로 내보내기 위해서 ch에 EOF를 넣어서 사용하는 것을 우리가 flush라고 관용적으로 부를뿐 모든 버퍼의 내보내기는 overflow 에서 관리를 한다