C언어에서 제공하고 있는 표준함수는 POSIX(Portable Operating System Interface)의 규정에 따라 함수를 제공하고 있으며, OS(UNIX/LINUX) 개발사 또는 Compiler 개발사에서 추가적인 확장 API들을 제공하는 것이 일반적이다. C언어를 활용하여 개발하는 개발자 입장에서는 시스템 콜 함수(System Call function)이든 라이브러리 콜 함수(Library Call Function)이든 단지 함수의 형태이므로 특별히 구별되지 않는다. 그러나 System Call Function이 자주 호출되면 시스템 성능에 영향을 주기때문에 최대한 자제해야 한다. System Call Function과 Library Call Function의 차이에 대해서 알고 사용하면 더 효율적인 프로그램을 작성할 수 있을 것이다.
System Call Function은 UNIX/LINUX와 같은 OS(Operating System)의 Kernel에 서비스를 요청할 때에 호출하는 함수를 말한다. 이 들은 주로 hardware와 관련된 서비스나 프로세스의 생성/종료, 파일의 I/O 등을 처리하며 System Call 시에는 프로그램이 User 모드가 아닌 Kernel 모드로 실행된다. 잦은 System Call은 시스템 resource를 효율적으로 사용할 수 없다. 대표적인 System Call Function으로는 fork, execve, _exit, kill, open, read, write, close 등의 함수가 있다.
Library Call도 내부적으로는 System Call을 사용하기도 하지만, 개발을 쉽게 할 수 있도록 기능을 제공한 Utility성 함수, System Call을 최소화 하기 위한 Wrapping 함수들이 있다. 대표적인 Library Call Function으로는 Utility성 함수인 strcmp, strcpy, strlen, memset 등과 System Call 최소화를 위한 fopen, fclose, fread, fwrite, exit, malloc, free 등의 함수들이 있다.
System Call / Library Call 함수의 특징
1. Return type 및 값의 차이
System Call Function의 return type은 대부분 int이며, 오류는 -1이고 정상이면 0 또는 1이상의 값을 return한다. 또한, 오류(return 값이 -1)이면 상세 오류 내용에 대해서는 errno라는 전역변수에 오류 코드가 저장된다. 오류 내용을 문자열로 표시하기 위해서는 strerror(errno)를 통해서 확인할 수 있다.
Library Call Function의 return type은 pointer, void, int 등 function의 목적에 따라 다양하다. 내부적으로 System Call Function을 호출하다가 오류가 발생한 경우에 대해서는 errno에 오류 코드가 설정되기도 한다.
2. UNIX / LINUX manual의 Section 번호 차이
UNIX/ LINUX의 매뉴얼은 명령어 man (manual)을 통해서 제공되고 있으며, manual은 manual의 영역에 따라 section 번호를 제공하는 데, System Call Function은 section 번호 2번을 사용하고, Library Call Function은 section 번호 3번을 사용한다.
※ 참고: Manual Section 번호의 의미
1: User Commands
2: System Call Function
3: Library Call Function,
4: Special Files
5: File Formats
6: Games,
7: Conventions and miscellany
8: Administration and privileged commands
(System Call Function의 manual 예 : 최상단에 READ(2)에서 괄호안의 숫자가 2이다.)
(Library Call Function의 manual 예 : 최상단에 FREAD(3)에서 괄호안의 숫자가 3이다.)
3. 메모리 할당 여부
System Call Function은 프로그램 내부에서 메모리를 할당 또는 해제하지 않는다. 메모리 할당이 필요한 경우에는 반드시 외부에서 할당하여 parameter로 넘겨야 한다. Library Call Function은 내부에서 메모리를 할당하여 return할 수도 있다.
(내부에서 메모리 할당되어 return 되는 예)
void *malloc(size_t size);
FILE *fopen(const char *filename, const char *mode);
위와 같이 malloc 함수처럼 메모리 할당은 OS 고유의 기능인데도 불구하고 malloc함수는 내부에 메모리를 할당하여 return 하므로 system call function이 아니다.
System Call 대체 함수
File I/O를 위한 함수로서 System Call function으로는 open/read/write/close 등이 있으며, Library Call Function은 fopen/fread/fwrite/fprintf/fclose 등이 있다. 이들 System Call Function은 File에서 read(2)/write(2)를 호출할 때마다 Kernel I/O가 발생하며 바로 바로 파일에 기록된다. (OS 내부에서 caching을 할 수도 있지만)
그러나 Library Call Function은 File에 read / write시에 특정 size(BUFSIZE 상수값의 크기)의 데이터가 모일 때까지 read / write를 하지 않고 buffer 크기보다 커졌을 때에 내부적으로 read / write를 한번만 실행하여 resource를 효율적으로 사용하게 된다. fwrite(3) 등으로 write한 데이터가 write되지 않고 남겨진 경우에 대해서는 fflush(3) 또는 fclose(3)를 수행시에 buffering된 데이터는 Disk에 write된다. 만약에 프로그램에서 실수로 fclose(3)를 하지 않고 종료를 하는 경우에는 어떻게 될까? 그것은 아래의 exit(3) 함수가 책임진다. (main( )함수의 종료도 exit(3)호출과 같은 효과가 있음)
System Call Function으로 오해하기 쉬운 Function으로는 exit(3)이 있는 데, 이는 프로세스를 종료하는 Library Call Function이다. 이에 대응하는 System Call은 _exit(2)이다. exit(3)은 _exit(2)을 wrapping한 function으로 fopen(3)으로 열어 둔 모든 FILE *를 close한다. 이를 통해서 저장되지 않은 메모리의 데이터는 파일에 저장된다. 만약 fclose(3)로 FILE*를 close하지 않은 상태에서 _exit(2) System Call 함수를 호출하여 프로그램을 종료하거나 비정상적으로 프로세스가 종료된다면 메모리에 남겨진 미 저장된 데이터는 File에 write되지 않고 사라지게 된다.
'C언어 > 기초' 카테고리의 다른 글
File처리 함수 어떤 것을 사용할 것인가? open(2) / fopen(3) (0) | 2019.10.01 |
---|---|
.h (Header) 파일 만드는 법 (0) | 2019.09.22 |