미래와 연결될 첫걸음

#2.3 System Structures - System Calls 본문

Infra/OS

#2.3 System Structures - System Calls

Traveler:) 2022. 1. 12. 02:38

System calls은 OS가 제공하는 service들에게 Interface를 제공합니다. 

이 System calls은 일반적으로 C나 C++, 더 low-level로는 assembly 언어로 쓰여진 routine들로 사용가능합니다. 

 

이 System call이 어떻게 쓰이지는 예를 들면, 

어떤 한 File을 읽고, 여기에 적힌 내용을 다른 파일에 복사하는 프로그램을 작성하는 상황이라고 해봅시다.

 

먼저 이 프로그램에 필요한 첫 Input은 두 File(Input File name, Ouput File name)의 이름일 것입니다.

이 이름들을 어떻게 받을지는 OS에 따라 다양한 방법으로 정해질 수 있습니다. 

한 방법은 사용자에게 이름을 직접 물어보는 것일 겁니다.

 

이러한 interactive system인 상황에서, 

사용자가 두 File의 이름을 정의하기 위해 키보드를 통해 입력(system call)한 character들을 읽고(system call) screen에 띄워줄(system call) 상황

 

마우스와 icon에 맞춘 system에서는,

window에 File name 메뉴가 나타나고(system call), 이 중에 사용자가 마우스로 input file 이름을 선택(system call). 그리고 output file이 window에 열리는(system call) 상황

 

이러한 상황이 있을 수 있습니다.

 

두 File 이름이 정해지고 나면, 프로그램은 반드시 input file 을 열고, output file을 생성해야 합니다. 각각의 기능들은 다른 system call이 필요합니다. 각 기능에서 에러를 체크하는 것도 추가적인 system call이 필요합니다. 예를 들어, 프로그램이 input file을 연다고 했을 때, input file이 존재하지 않을 수도 있고 아니면, 권한이 없어서 열지 못하는 상황이 있을 수 있습니다. 이러한 경우에는 프로그램은 console에 message를 출력하고(다른 연속된 system call 사용됨), 비정상적인 종료(다른 system call)를 해야합니다.

만약 input  file이 존재한다면, 프로그램은 새로운 output file을 생성해야만 합니다. 하지만, 이미 output file과 같은 이름을 가진 file이 존재한다면, 프로그램을 중단(다른 system call)시키든지 기존의 파일을 삭제(다른 system call)하든지 아니면 새로운 파일을 만들던지(다른 system call) 할 것 입니다. 또 다른 방법은 interactive system인 상황에서, 사용자에게 기존의 파일을 대체할(다른 system call) 것인지, 프로그램을 중단(다른 system call) 할 것인지 물어보는 것(연속된 system call)입니다.

 

두 File이 준비되고 나면, 프로그램은 input file에서 read(system call)해서 output file로 write(system call)하는 일을 반복 할 것입니다. 각 read와 write는 에러 없이 잘 read, write했는지 상태를 return 해주어야만 합니다. 프로그램은 input file의 끝에 잘 도착할 수도 있고 아니면 parity error와 같은 error로 인해 read에 실패할 수도 있습니다. write기능은 output 장치에 따라 메모리 공간이 없는 등 다양한 error를 만날 수 있습니다.

 

끝으로, 모든 File이 복사가 된 후, 프로그램은 두 File을 close(system call)하고 console 혹은 window에 message를 출력(system call)한 후, 정상적인 종료(system call) 를 합니다. 위의 과정이 아래의 사진을 통해 확인해 볼 수 있습니다.

 

Example of how system calls are used.

 

지금까지 살펴봤듯이, 이러한 간단한 프로그램도 OS를 상당히 사용합니다. 빈번하게 system들은 1초에 수천번의 system call를 실행시킵니다. 그러나 대부분의 프로그래머들은 이러한 자세한 수준을 보지 못합니다. 대부분은 application 개발자는 프로그램을 Application Progamming Interface(API)에 따라 만들기 때문입니다. API는 application 개발자들이 사용가능한 function들을 모아놓은 것입니다. parameter들를 function에 전달하거나 프로그래머들이 예상할 수 있는 return 값들을 포함해서 말이죠. 가장 대표적인 3가지 API는 Windows system에 맞춘 Windows API, POSIX에 기반한 system(UNIX, Linux, Mac OS)에 맞춘 POSIX API, Java 가상 머신에 프로그램이 실행될 수 있게 맞춘 Java API가 있습니다. 어떤 한 프로그래머는 OS가 제공하는 library를 통해 API에 접근합니다. UNIX, Linux인 경우에 C 언어로 쓰여진 프로그램이 있다면은 그 library는 'libc'(system call)에 의해 불려지게 됩니다. 각 OS는 각자의 system call 이름을 가지고 있습니다.

 

예를 들어, Window kernel에서, CreateProcess() (새로운 process를 생성하는 함수)가 사용될 때는 실제로는 NTCreateProcess() system call이 불려지게 됩니다.

 

Application 개발자가 system call을 직접 사용하지 않고, API를 사용하는 이유는 여러가지가 있습니다. 한가지 장점은 program portability에 있습니다. API를 사용해 프로그램을 만드는 application 개발자는 자신이 만든 프로그램이 같은 API를 제공하는 어떠한 system에서든지 잘 complie되고 실행되기를 기대합니다. 또, API를 사용하는 것이 system call을 사용해서 개발하는 것보다 더 쉽습니다. 그럼에도 API와 system call은 꽤 일치하는 점이 있습니다. 그리고 UNIX, Linux, Windows OS의 각 system call은 유사한 점이 많습니다.

 

run-time support system은 system-call interface(OS에 의해 system call이 사용하도록 하는 link)를 지원합니다. system call interface는 API에서 function이 실행되는 것을 인식하고, OS내에서 필요한 system call을 발생시킵니다. system call interface는 system call과 관련된 숫자들을 목록으로 하는 table을 유지합니다. 그런 다음, system call interface가 OS에서 system call을 발생시키고, system call의 상태를 나타내는 값과 어떤 return 값을 반환합니다. 

 

system call을 사용하는 사람은 system call이 어떻게 구현되어있고, 실행되는 동안 무엇을 하는지 알 필요가 없습니다. 보다, system call을 사용하는 사람 API를 잘 사용하고, system call 실행 결과를 잘 이해하기만 하면 됩니다. 따라서, OS interface의 자세한 부분은 거의 프로그래머에게 숨겨져있고, run time support library에 의해 관리됩니다. 아래 그림은 OS가 user application이 open() system call을 발생시키면 어떻게 되는지 나타내고 있습니다.

The handling of a user application invoking the open() system call.