일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- MAP
- non-blocking
- 스케줄링
- HashMap
- 알고리즘
- os 쓰레드
- 자바
- 쓰레드
- 유저 쓰레드
- Java
- 쓰레드 덤프
- avl
- 프로그래머스
- set
- 코테
- list
- black-red
- 트리
- 유저모드
- 코딩테스트
- tree
- synchronizeation
- 하드웨어 쓰레드
- Red-Black
- Lock
- 배열
- 커널모드
- linkedmap
- cpu
- OS
변수의 기록
(OS) 유저 모드와 커널 모드, 그리고 인터럽트와 시스템 콜 (예제 있음) 본문
유저 모드와 커널 모드, 그리고 인터럽트와 시스템 콜
1. 유저 모드 vs 커널 모드
모던 운영체제는 CPU의 실행 권한을 **유저 모드(User Mode)**와 **커널 모드(Kernel Mode)**로 나눔.
이유는 운영체제와 시스템 자원을 보호하기 위함임.
유저 모드
- 애플리케이션(사용자 프로그램)이 실행되는 환경
- CPU는 제한된 명령어만 사용 가능
- 직접 하드웨어 접근 불가 (예: 디스크, 메모리 제어, 네트워크 등)
- 문제가 발생하더라도 시스템 전체에는 영향을 미치지 않음
커널 모드
- 운영체제의 핵심인 커널이 실행되는 환경
- CPU는 모든 명령어 실행 가능 (하드웨어 제어 포함)
- 시스템 자원 관리 (메모리, CPU 스케줄링, 파일 시스템 등)
- 모든 프로세스의 보호와 보안을 책임짐
2. 모드 전환 (유저 모드 → 커널 모드)
유저 모드에서 커널 모드로 전환되는 시점은 다음 두 가지 경우임
- 시스템 콜 호출
- 인터럽트 발생
전환 시 CPU는 현재 작업 중인 프로그램 상태(레지스터, PC 등)를 저장한 뒤 커널 코드로 진입함.
작업이 완료되면 다시 상태를 복원하고 유저 모드로 돌아감.
3. 시스템 콜 (System Call)
시스템 콜은 유저 프로그램이 OS 커널에 기능을 요청할 때 사용하는 인터페이스.
즉, 유저 모드에서 직접 하드웨어를 제어하지 않고 커널에게 "요청"하는 방식임.
예시 (주요 시스템 콜 종류)
시스템 콜 종류 | 설명 |
read() / write() | 파일 입출력 |
open() / close() | 파일 열기, 닫기 |
fork() / exec() | 프로세스 생성, 프로그램 실행 |
wait() / exit() | 프로세스 대기, 종료 |
socket() / bind() / accept() | 네트워크 소켓 처리 |
kill() | 시그널 전송 |
* 근데 개발을 할때 os 시스템 콜을 우리는 직접 쓴 적이 있을까?
그동안 개발을 하면서 다음과 같은 작업을 수도 없이 해왔을 것임:
- 파일을 열고 읽거나 저장하고
- 네트워크로 데이터를 보내고 받고
- 새로운 쓰레드나 프로세스를 만들고 관리하고
그런데 여기서 한 가지 질문.
"우리는 직접 시스템 콜을 호출한 적이 있는가?"
예를 들어, open(), read(), write() 같은 시스템 콜을 직접 코드에 적은 적이 있었는가?
아마 대부분은 없음.
그렇다면 또 이런 질문이 생김.
"우리는 시스템 콜을 직접 호출한 적이 없는데, 어떻게 그런 기능들을 사용해온 걸까?"
답은 이렇다.
→ 우리가 사용하는 **고수준 언어(Java, Python 등)**는 시스템 콜을 직접 노출하지 않음.
대신, **내부적으로 시스템 콜을 래핑(wrapping)**해서 제공하는 API나 라이브러리를 통해 간접적으로 사용하게 해줌.
예:
FileInputStream fis = new FileInputStream("data.txt");
이 한 줄이 실제로는 커널에게:
- "data.txt" 파일을 열어줘 (open 시스템 콜)
- "내용을 읽어와줘 (read 시스템 콜)"
같은 요청을 보내는 것과 같음. 단지 그걸 우리가 직접 쓰지 않았을 뿐.
결국 우리가 시스템 콜을 직접 호출하지 않아도, 항상 그 기능을 '간접적으로' 사용하고 있었던 것임.
4. 인터럽트 (Interrupt)
인터럽트는 예기치 않은 사건을 CPU에 알리는 메커니즘임.
인터럽트가 발생하면 CPU는 현재 작업을 중단하고 커널 모드로 전환하여 해당 인터럽트에 대응함.
인터럽트 종류
구분 | 예시 | 설명 |
하드웨어 인터럽트 | 키보드 입력, 마우스 클릭, 네트워크 패킷 수신 등 | 장치가 CPU에 직접 신호를 보냄 |
소프트웨어 인터럽트 | 시스템 콜, 예외 상황 | 프로그램 내부에서 명시적으로 발생시키거나 오류 발생 시 |
인터럽트 처리 흐름
- 장치 또는 소프트웨어가 인터럽트 신호 발생
- CPU는 현재 상태 저장 (컨텍스트 스위칭)
- 커널 모드 진입
- 해당 인터럽트에 등록된 인터럽트 핸들러 실행
- 처리 완료 후 원래 유저 모드로 복귀
예:
- 사용자가 마우스 클릭 → 마우스 컨트롤러가 인터럽트 발생
- CPU가 이를 받아 마우스 인터럽트 핸들러 실행
- OS가 클릭 좌표 확인, 클릭된 아이콘 실행
- 아래 파일 read 흐름
1. 유저모드 : t1 파일 요청 (system call)
-> * 시스템 콜 발생 시 CPU는 자동으로 커널 모드 진입함
2. 커널모드 : t1 cpu 상태 저장 , ssd로 파일 읽을 준비 , t1 wating , t2 running
-> * 이때 I/O 작업은 비동기 처리, 즉 SSD가 읽는 동안 CPU는 다른 일 함
3. 유저모드 : 인터럽트 발생 (이유 : 파일 ssd에서 다 읽음)
-> * 이건 **디스크 컨트롤러(하드웨어 장치)**가 인터럽트를 발생시킴
4. 커널모드 : t2 상태 저장 , t1 ready , t2 cpu 상태 복원
5. 유저모드 : 인터럽트 발생 (이유 : 타임슬라이스 cpu점유 시간 다씀)
->* 이건 타이머 인터럽트로, OS가 강제로 CPU 점유를 회수
6. 커널모드 : t2 cpu 상태 저장, t2 ready , t1 running , t1 cpu 상태 복원
5. 왜 커널 모드를 만들어서 보호하는가?
운영체제는 전체 시스템 자원을 통제하고 관리함.
이걸 모든 프로그램이 직접 접근할 수 있게 허용하면 보안 위협, 시스템 충돌이 발생할 수 있음.
커널 모드는 이런 위험을 차단하고, 엄격한 통제 하에 커널만이 민감한 작업을 수행하도록 설계됨.
유저 프로그램은 오직 시스템 콜을 통해서만 커널과 통신할 수 있음.
6. 정리
- 일반 애플리케이션은 유저 모드에서 동작
- 시스템 자원이 필요하거나 하드웨어 사건이 발생하면 커널 모드 진입
- 인터럽트는 예상치 못한 사건을 CPU에 알리는 신호
- 시스템 콜은 유저 프로그램이 커널에 기능을 요청하는 방법
- Java, Python 등은 내부적으로 시스템 콜을 감싼 API를 통해 커널 기능 사용
- 커널 모드는 시스템 보호와 안정성을 위한 핵심 기제임
'CS지식 > 운영체제 (Operating System)' 카테고리의 다른 글
(os) 커널이란 무엇인가? (예시 포함 아주 쉽게 설명) (0) | 2025.04.15 |
---|---|
(OS) 스레드의 종류 (하드웨어, OS, 유저 , 그린 ,커널) (0) | 2025.04.14 |
(OS) CPU 스케줄러와 디스패처, 그리고 스케줄링 알고리즘 총정리 (0) | 2025.04.13 |
(OS) 자바 스레드의 상태 – OS 프로세스 상태 비교 (0) | 2025.04.13 |
(OS) 데드락이란? (발생조건 , 해결방안 포함) (0) | 2025.04.12 |