응용 프로그램이 운영체제에 동작을 요청하는 인터페이스. 하드웨어를 간접적으로 제어하고 운영체제가 관리하는 정보에 접근하기 위한 규약이다.
하드웨어를 대신 만지는 쪽
사용자 프로그램은 하드웨어를 직접 제어할 수 없다. 중간에 있는 운영체제가 대신 해준다.
운영체제는 메모리에 프로그램을 올리고, 입출력을 처리하고, 파일 시스템을 다루는 여러 서비스를 제공한다. 사용자 프로세스는 여기에 직접 손대는 대신 시스템 콜을 호출해서 서비스를 받는다.
호출의 갈래
프로세스를 제어하는 exit, abort, fork, execute, wait가 있고 메모리를 할당하고 푸는 brk, sbrk, mmap이 있다. 파일 쪽은 create, delete, open, close, read, write이고, 장치 쪽은 하드웨어의 상태를 읽고 제어하는 ioctl과 장치를 요구하고 방출하는 호출들이다.
나머지 셋은 시스템 자체를 다룬다. getpid, alarm, sleep, time, date처럼 정보를 얻고 유지하는 것, pipe, shm_open, mmap처럼 프로세스끼리 통신하는 것, 파일 권한을 설정하는 것 같은 보호에 해당하는 것이다.
파일을 열고 읽고 쓰는 일, 프로세스를 만들고 끝내는 일, 메모리를 할당하는 일이 전부 시스템 콜이다. 평범해 보이는 프로그램도 실행되는 내내 커널에 요청하고 있다.
API와 다른 점
시스템 콜은 API의 일종이지만, 운영체제의 기능을 호출하는 데에만 쓰인다는 점에서 다른 API와 구분된다.
인터페이스는 사양만 정해놓은 것이라 같은 인터페이스라도 구현은 운영체제마다 다르다. 윈도우와 유닉스의 함수 모양이 서로 다르게 생긴 이유다.
라이브러리를 거치는 호출
실제 코드에서 시스템 콜을 직접 부르는 일은 드물다. 대개 라이브러리 함수를 통해 간접적으로 쓴다. 자바에서 System.out.println을 부르면 그 아래 어딘가에서 쓰기 시스템 콜이 불린다.
모드 전환 비용
시스템 콜은 유저 모드에서 커널 모드로 전환된다. 그 전환에 비용이 든다.
입출력이 많은 프로그램이 느린 이유 중 하나가 이것이고, 출력을 버퍼에 모았다가 한 번에 내보내는 것이 빠른 이유이기도 하다. 시스템 콜 횟수 자체를 줄이는 것이다. 자세한 것은 입출력 성능에 있다.
참고
원본 노트는 malloc과 free를 프로세스 제어 시스템 콜로 적어두었다. 둘은 C 표준 라이브러리 함수이고, 실제 시스템 콜은 그 아래의 brk, sbrk, mmap이다. malloc은 그 위에서 힙을 관리하는 사용자 공간 코드다. POSIX malloc