본문 바로가기
Unix

[unix] 시스템 콜(System Call)

by mdesign 2024. 8. 28.

시스템 콜(System Call)은 운영체제의 커널이 사용자 프로그램에게 제공하는 인터페이스입니다. 사용자 프로그램이 하드웨어나 운영체제의 핵심 기능에 접근하려면, 시스템 콜을 통해 운영체제에 요청을 전달해야 합니다.

 시스템 콜의 주요 개념


1. 커널 모드와 사용자 모드:

   - 커널 모드(Kernel Mode): 운영체제의 커널이 실행되는 모드로, 하드웨어 자원에 직접 접근하고 제어할 수 있는 높은 권한을 가집니다.
   - 사용자 모드(User Mode): 사용자 애플리케이션이 실행되는 모드로, 제한된 권한만 가지고 있으며, 직접 하드웨어에 접근할 수 없습니다. 사용자 모드에서 하드웨어 자원에 접근하려면 커널 모드로 전환해야 합니다.


2. 시스템 콜의 역할:

   - 사용자 프로그램은 직접 하드웨어 자원에 접근할 수 없으므로, 시스템 콜을 통해 커널에게 특정 작업(예: 파일 읽기, 메모리 할당, 프로세스 생성 등)을 요청합니다.
   - 시스템 콜은 사용자 모드에서 커널 모드로의 전환을 유도하며, 요청한 작업이 완료되면 다시 사용자 모드로 돌아갑니다.


3. 컨텍스트 스위칭:

   - 시스템 콜이 호출되면, 운영체제는 사용자 모드에서 커널 모드로 전환하며, 이 과정에서 컨텍스트 스위칭이 발생합니다. 컨텍스트 스위칭은 프로세스의 현재 상태를 저장하고, 새로운 상태로 전환하는 작업을 의미합니다.
   - 이 과정은 CPU 자원을 소비하는 오버헤드를 발생시킬 수 있으나, 시스템의 안전성과 안정성을 보장하는 데 필수적입니다.


 시스템 콜의 종류


Unix 시스템에서 제공하는 시스템 콜은 매우 다양하며, 주요 카테고리별로 정리하면 다음과 같습니다:


1. 프로세스 관리:

   - `fork()`: 현재 프로세스의 복사본을 생성하여 새로운 프로세스를 만듭니다.
   - `exec()`: 현재 프로세스를 다른 프로그램으로 대체합니다.
   - `wait()`: 자식 프로세스가 종료될 때까지 부모 프로세스가 기다립니다.
   - `exit()`: 현재 프로세스를 종료합니다.


2. 파일 관리:

   - `open()`: 파일을 열거나 생성합니다.
   - `read()`: 파일에서 데이터를 읽습니다.
   - `write()`: 파일에 데이터를 씁니다.
   - `close()`: 열린 파일을 닫습니다.
   - `unlink()`: 파일을 삭제합니다.


3. 디렉토리 및 파일 시스템 관리:

   - `mkdir()`: 새 디렉토리를 만듭니다.
   - `rmdir()`: 빈 디렉토리를 삭제합니다.
   - `chdir()`: 현재 작업 디렉토리를 변경합니다.
   - `getcwd()`: 현재 작업 디렉토리의 경로를 얻습니다.


4. 메모리 관리:

   - `brk()`, `sbrk()`: 프로세스의 데이터 영역을 확장하거나 축소하여 메모리를 동적으로 할당합니다.
   - `mmap()`: 파일을 메모리에 매핑하여 파일을 메모리처럼 접근할 수 있게 합니다.


5. 통신 및 네트워크:

   - `socket()`: 네트워크 통신을 위한 소켓을 생성합니다.
   - `bind()`: 소켓에 주소를 연결합니다.
   - `listen()`: 소켓을 통해 연결 요청을 대기합니다.
   - `accept()`: 소켓을 통해 들어오는 연결 요청을 수락합니다.
   - `connect()`: 원격 서버에 연결을 요청합니다.


6. 시스템 정보:

   - `getpid()`: 현재 프로세스의 프로세스 ID를 반환합니다.
   - `getuid()`: 현재 사용자의 사용자 ID를 반환합니다.
   - `gettimeofday()`: 현재 시간을 얻습니다.


 시스템 콜의 사용 예


다음은 `open()`, `read()`, `write()`, `close()`와 같은 시스템 콜을 사용하는 간단한 C 프로그램 예제입니다.

#include 
#include 

int main() {
    int fd;
    char buffer[128];
    ssize_t bytesRead;

    // 파일을 읽기 모드로 엽니다.
    fd = open("example.txt", O_RDONLY);
    if (fd < 0) {
        return 1; // 파일 열기에 실패하면 종료
    }

    // 파일에서 데이터를 읽습니다.
    bytesRead = read(fd, buffer, sizeof(buffer) - 1);
    if (bytesRead < 0) {
        return 1; // 읽기에 실패하면 종료
    }

    // 버퍼에 읽은 데이터를 널 종단 문자로 종료시킵니다.
    buffer[bytesRead] = '\0';

    // 표준 출력으로 데이터를 씁니다.
    write(STDOUT_FILENO, buffer, bytesRead);

    // 파일을 닫습니다.
    close(fd);

    return 0;
}

 


 시스템 콜의 중요성

- 추상화: 시스템 콜은 하드웨어와의 직접적인 상호작용을 추상화하여 개발자가 복잡한 세부사항을 신경 쓰지 않고 프로그래밍할 수 있게 합니다.
- 안정성: 시스템 콜을 통해 자원에 접근하면, 커널이 모든 자원 접근을 통제하고 관리하므로 시스템의 안전성을 보장합니다.
- 이식성: 다양한 Unix 계열 운영체제에서 동일한 시스템 콜 인터페이스를 제공하므로, 코드의 이식성이 높아집니다.


 요약

시스템 콜은 사용자 프로그램이 운영체제의 핵심 기능을 활용할 수 있게 해주는 중요한 인터페이스입니다. 시스템 콜을 통해 프로그램은 파일 관리, 프로세스 제어, 메모리 관리 등 다양한 작업을 수행할 수 있으며, 이러한 기능을 통해 운영체제와 프로그램이 긴밀하게 상호작용하게 됩니다.