1. 동시성 제어 (Concurrency Control)

  • Context-Switch : CPU에서 running 중이던 process를 PCB에 store 하고, 다른 PCB의 register 정보(PC, IR)를 CPU에 load 해오는 상황
  • Concurrency-Control : Context-Switch 를 통해서 time-sharing을 함. 즉, 동시성 = 시분할

 

2. Concurrent vs Parallel

  • Concurrenct : 시분할
  • Parallel : multicore에서 실제 동시에 병렬적으로 실행 Parallelism
    1. data parallelism
    2. task parallelism

 

3. 동기(synchronous) vs 비동기(asynchronous) / blocking vs non-blocking

  • Synchronous VS Asynchronous
    • 두 가지 이상의 대상(메서드, 작업, 처리 등)과 이를 처리하는 시간으로 구분한다.
    • Synchronous
      • 호출된 함수의 리턴하는 시간과 결과를 반환하는 시간이 일치하는 경우
      • 함수의 결과를 호출한 쪽에서 처리
    • Asynchronous
      • 호출된 함수의 리턴하는 시간과 결과를 반환하는 시간이 일치하지 않는 경우
      • 함수의 결과를 호출한 쪽에서 처리하지 않는다.
      • 호출되는 함수에게 callback을 전달해서, 호출되는 함수가 전달받은 callback을 실행
  • Blocking VS Non-Blocking
    • 호출되는 대상이 직접 제어할 수 없는 경우 이를 구분할 수 있다.
    • Blocking: 호출된 함수가 자신의 작업을 모두 마칠 때까지 호출한 함수를 기다리게 만든다.
    • Non-Blocking: 호출된 함수가 바로 리턴해서 호출한 함수에게 제어권을 준다.

 

4. 동기화 객체의 종류

  • 스레드 동기화 방법
    1. 실행 순서의 동기화
      • 스레드의 실행 순서를 정의하고, 이 순서에 반드시 따르도록 하는 것
    2. 메모리 접근에 대한 동기화
      • 메모리 접근에 있어서 동시 접근을 막는 것
      • 실행의 순서가 중요한 상황이 아니고, 한 순간에 하나의 스레드만 접근하면 되는 상황을 의미
  • 동기화 기법의 종류
    1. 유저 모드 동기화
      • 커널의 힘을 빌리지 않는(커널 코드가 실행되지 않는) 동기화 기법
      • 성능상 이점, 기능상의 제한
      • Ex) 크리티컬 섹션 기반의 동기화, 인터락 함수 기반의 동기화
    2. 커널 모드 동기화
      • 커널에서 제공하는 동기화 기능을 활용하는 방법
      • 커널 모드로의 변경이 필요하고 이는 성능 저하로 이어짐, 다양한 기능 활용 가능
      • Ex) 뮤 텍스 기반의 동기화, 세마포어 기반의 동기화, 이름있는 뮤텍스 기반의 프로세스 동기화, 이벤트 기반의 동기화

 

 

5. 동기화 관련 문제들

  1. busy-waitingsleep and wakeup으로 해결
  2. 생산자 소비자 문제 (Producer-Consumer)
    • 생산자 (producer) : 버퍼에 정보를 삽입
    • 소비자 (consumer) : 버퍼에서 정보를 제거
    • 버퍼가 가득 차 있다면? 생산자를 sleep --> 소비자 수행 후, wakeup
    • count에 대한 접근 → Race-Condition (경쟁 조건) → wakeup signal 분실 가능
    • 해결 : 세마포어 활용
  3. 식사하는 철학자들 문제
    • 철학자는 스파게티를 먹기 위해 양옆의 포크를 동시에 들어야 한다.
    • 이때, 전부 왼쪽 포크를 먼저 들면, 오른쪽 포크를 전부 못 들어 무한정 기다리게 된다.
    • 즉, 제한된 수의 자원에 접근하는 문제
    • 동시성 + 데드락 : 여러 프로세스가 동시에 돌아갈 때 교착 상태에 빠지는 원인
    • 해결 : 동시성을 제거 - 필요한 포크가 사용 중이라면, 배고픈 철학자라도 블락된다
  4. 독자 저자 문제 (The Readers and Writers Problem)
    • 식사하는 철학자 문제가 I/O와 같이 제한된 수의 자원에 접근하는 문제라면
    • 읽는 자 쓰는 자는 데이터베이스에 접근하는 모델
    • 여러 리더가 존재 가능
    • Reader와 Writer의 배타적 접근
    • 해결 : 뮤 텍스 세마포어
  5. 잠자는 이발사 문제
    • 한 명의 이발사, 하나의 이발용 의자, 기다리는 손님을 위한 n개의 의자
    • 손님이 없으면 이발사는 sleep
    • 손님이 오면 이발사는 wakeup
    • 이발 중 손님이 오면 대기용 의자에서 기다림
    • 대기용 의자도 만석이면 손님은 그냥 이발소를 떠남
    • ⇒ 이발사와 손님이 Race-Condition에 빠지지 않도록 하는 것
    • 해결 : 뮤 텍스
      • 한 번에 한 명만이 동작 상태를 바꿀 수 있게 한다.
      • 이발사 : 뮤 텍스 얻어야 대기실 손님 확인 가능
      • 손님 : 뮤텍스 얻어야 이발소 들어갈 수 있음, 대기실 or 의자에 앉으면 뮤텍스 반납
    • 복수의 잠자는 이발사 문제 : 세마포어 필요

 

6. Critical Section (임계 영역)

  • 멀티 스레딩에 문제점에서 나오듯, 동일한 자원을 동시에 접근하는 작업을 실행하는 코드 영역
  • Race Condition을 유발하는 코드 블록
  • (e.g. 공유하는 변수 사용, 동일 파일을 사용하는 등)

 

7. Race Condition 이란?

  • 공유 자원에 대해 여러 프로세스/스레드가 동시에 접근을 시도하는 상황
  • 즉, 하나의 자원을 두고 경쟁하는
  • 타이밍에 따라서 결과가 다를 수 있어, 자료의 일관성을 해치는 결과가 나타남
  • ex) 은행에서 출금하는 스레드 사이에서 발생하는 경우 balance가 덜 줄어듦 → 심각한 문제
    1.  

 

8. Race Condition이 발생하는 경우

  • Shared resource에 access 했는데 동기화를 하지 않으면 발생
  1. 커널 작업을 수행하는 중에 인터럽트 발생
    • 문제점 : 커널 모드에서 데이터를 로드하여 작업을 수행하다가 인터럽트가 발생하여 같은 데이터를 조작하는 경우
    • 해결법 : 커널 모드에서 작업을 수행하는 동안, 인터럽트를 disable 시켜 CPU 제어권을 가져가지 못하도록 한다.
  2. 프로세스가 'System Call'을 하여 커널 모드로 진입하여 작업을 수행하는 도중 문맥 교환이 발생할 때
    • 문제점 : 프로세스 1이 커널 모드에서 데이터를 조작하는 도중, 시간이 초과되어 CPU 제어권이 프로세스2로 넘어가 같은 데이터를 조작하는 경우 ( 프로세스2가 작업에 반영되지 않음 )
    • 해결법 : 프로세스가 커널모드에서 작업을 하는 경우 시간이 초과되어도 CPU 제어권이 다른 프로세스에게 넘어가지 않도록 함
  3. 멀티 프로세서 환경에서 공유 메모리 내의 커널 데이터에 접근할 때
    • 문제점 : 멀티 프로세서 환경에서 2개의 CPU가 동시에 커널 내부의 공유 데이터에 접근하여 조작하는 경우
    • 해결법 : 커널 내부에 있는 각 공유 데이터에 접근할 때마다, 그 데이터에 대한 lock/unlock을 하는 방법

 

9. Thread-safe 의미, 구현

  • 의미
    • 멀티스레드 환경에서 여러 스레드가 동시에 하나의 객체 및 변수(공유 자원)에 접근할 때, 의도한 대로 동작하는 것
  • 구현
    • 결국 동기화
    • 2개의 critical regionmutual exclusive 하게 수행되도록 막아서, 2개의 thread를 synchronize 하면 Race-condition을 없앨 수 있다.

 

10. Critical Section Problem (임계 영역 문제)를해결하기 위한 조건

  1. 상호 배제 (Mutual Exclusion) : 한 프로세스가 임계 구역에 들어가 있으면 다른 프로세스 들어갈 수 없다.
  2. 진행 (Progress) : 임계구역에 들어간 프로세스 없다면 어느 프로세스가 들어갈지 적절히 선택
  3. 한정 대기 (Bounded Waiting) : 기아 방지를 위해 한 번 들어갔다 나온 프로세스는 다음에 들어갈 때 제한을 준다. - no Starvation

(+) CPU의 속도 등에 대한 어떠한 가정도 하면 안 된다

 

 

11. Mutex (Mutual Exclusive), 상호 배제

  • Mutual exclusive 하게 수행하도록 하여 synchronize 하는 것
  • 그러므로 Race Condition을 없앤다.
  • 화장실이 하나뿐인 식당, 열쇠 1개
  • 여러 프로세스/스레드가 공유된 자원에 접근하는 것을 막는 것
  • 여러 프로세스가 공유 자원 사용하려 할 때 번갈아 가며 사용하도록 함
  • 임계 구역 내에서 인터럽트, 교착상태, 무한반복 발생하지 않도록 해야 함
  • 키가 1개인 세마포어라고 볼 수 있다. (이진 세마포어)
  • 구현 방법
    • 2개 프로세스 기준 : 데커 알고리즘, 피터슨 알고리즘
    • 여러 개 프로세스 기준 : Lamport의 빵집 알고리즘

 

 

12. Critical Section Problem 해결 방법 4가지

  1. Lock
  2. Semaphore
  3. Monitor
  4. Message

 

13. Lock

  • 자원을 사용하는 동안 들어오지 못하도록 잠구는 것
  • 하나의 자원에 여러 스레드가 동시에 접근하는 것을 조율해준다.

1) 기본형

  • 동시에 공유 자원에 접근하는 것을 막기 위해 Critical Section에 진입하는 프로세스는 Lock을 획득하고 Critical Section 을 빠져나올 때, Lock 을 방출함으로써 동시에 접근이 되지 않도록 한다.
while (lock == 1);
lock = 1;
Critical_region();
lock = 0;
  • 한계 : lock 이 0 일 때 두 스레드가 동시에 진입하면 문제!

2) Spin Lock

  • busy waiting을 사용한 lock
  • 장점 : lock이 해제될 때 context-switching 이 없어서, 오버헤드 없이 critical section 접근 가능
  • 단점 : 어떤 스레드가 락을 오래 소유하면, CPU 낭비
  • 한계 : Progress를 만족하지 않음 - 010101 번갈아서 들어와야 함 / 000 이면 실행 안됨
  • 언제 사용? 멀티-스레드에서 critical section 이 아주 작거나, 빠른 처리 가능할 때
while(True) {
	while (turn != 0);
	Critical_region();
	turn = 1;
	Noncritical_region();
}

 

while(True) {
	while (turn != 1);
	Critical_region();
	turn = 0;
	Noncritical_region();
}

 

3) Peterson's Solution

  • 소프트웨어적으로 이 방법을 쓰면 해결 가능하지만, 오버헤드가 크다

4) TSL (Test and Set Lock) instruction

  • 하드웨어적으로 제공되는 명령어로 atomic 하게 실행된다.
# 하드웨어에서 이런 명령어를 제공
bool Test_and_Set(bool *flag) {
	bool old = *flag;
	*flag = True;
	return old;
}

lock = false;
repeat
	while Test_and_Set(lock) do no-op;
	Critical Section
	lock = false;
	Remainder Section
until false
  • 문제
    • Spin Lock 이기 때문에 CPU를 계속 써야 함 (Lock 값 계속 체크해야 함)

 

 

14. Sleep and Wakeup

  • busy-waiting 해결 → 임계 구역 진입이 허용되지 않을 때, CPU 시간을 낭비하는 대신 블록 하는 프로세스 간 통신 고려
    • sleep : 호출자를 block → 다른 프로세스가 깨울 때 (wakeup)까지 보류
    • wakeup
  • 발생 문제 : 생산자 - 소비자 문제 (한정된 버퍼 문제)
    • 생산자 (producer) : 버퍼에 정보를 삽입
    • 소비자 (consumer) : 버퍼에서 정보를 제거
    • 버퍼가 가득 차 있다면? 생산자를 sleep --> 소비자 수행 후, wakeup

 

 

15. Semaphore

  • 화장실이 여러 개 있는 레스토랑, 열쇠 = 칸 개수만
  • 현재 공유자원에 접근할 수 있는 프로세스/스레드 수를 나타내는 값을 두어 상호 배제
  • Lock시 특정 수만큼의 카운트를 더하고
  • Unlock시 빼주는 형식으로 처리
  • 이런 락을 슬립( Sleep ) 가능한 락이라고 함
  • Up, Down은 atomic 하게 동작
  • 생산자 소비자 문제의 근본적 해결
  • 동기화해야 하는 대상이 여러 개일 때 사용

1) 카운팅 세마포어

  • 가용한 개수를 가진 자원에 대한 접근 제어용으로 사용되며, 세마포는 그 가용한 자원의 개수로 초기화된다. 자원을 사용하면 세마포가 감소, 방출하면 세마포가 증가한다.
  • 생산자 소비자 문제와 비교하기
  • count 하나로 표현되던 부분들이 up, down을 이용하여 mutex, empty, full로 표현
#define N 100   // 버퍼 용량
int mutex = 1;  // 공유 데이터를 위한 mutex
int empty = n   // 빈 용량
int full = 0    // 찬 용량

void producer(void) {
	int item;

	while(TRUE) {
		item = produce_item();  // item 생성
		down(&empty);           // if 꽉차지 않았으면 empty--;
		down(&mutex);           // mutex = 0 으로 해서, lock 처리
		insert_item(item);      // 버퍼에 추가
		up(&mutex);             // mutex = 1 으로 해서, unlock 처리
		up(&full);
	}
}

void consumer(void) {
	int item;

	while(TRUE) {
		down(&full);
		down(&mutex);
		item = remove_item();  // 
		up(&mutex);
		up(&empty);
		consume_item(item);  
	}
}

2) 이진 세마포어 (MUTEX)

  • MUTEX라고도 부르며, 상호 배제의 (Mutual Exclusion)의 머릿글자를 따서 만들어졌다. 이름 그대로 0과 1 사이의 값만 가능하며, 다중 프로세스들 사이의 Critical Section 문제를 해결하기 위해 사용한다.

 

16. Monitor

  • 동기화를 구현하기 위한 특수 프로그램 기법
  • 특정 공유 자원을 프로세스에게 할당하는 데 필요한 데이터와 이 데이터를 처리하는 프로시저로 구성
  • 자료 추상화, 정보 은폐 개념을 기초, 병행성 구조
  • 상호 배제가 low-level 단에서 지원됨
  • → "단 하나의 프로세스만 한 순간에 모니터에서 활동할 수 있다."
  • 생산자-소비자 문제 해결
    • 조건 변수 wait, signal 도입
    • sleep, wakeup과 달리 모니터에서는 자동적으로 상호 배제가 됨→ 문맥교환 될 걱정하지않고 연산 완료 가능
    • → wait, signal은 상호배제가 아님

 

17. Message Passing

  • send / receive ; 시스템 호출 일종
  • acknowledgement 분실 문제 -> 메시지 구별 필요
  • 인증 --> 프로세스의 유일성 보장
  • 생산자 - 소비자 문제
    • 공유 메모리가 아닌, 메시지 전달로 해결
    • 가정
      1. 모든 메시지는 동일한 크기
      2. 메시지는 운영체제에 의해 자동 버퍼링
    • 방법
      1. 소비자는 시작할 때, N개의 빈 메시지를 생산자에게 보냄
      2. 생산자는 소비자에게 전달할 아이템을 생산하면, 빈 메시지 수신 → 아이템이 들어 있는 메시지 전송

'CS > 운영체제 (OS)' 카테고리의 다른 글

8. IPC (Inter-Process Communication)  (0) 2021.08.11
7. 프로세스 vs 스레드  (0) 2021.08.11
4. 프로세스의 주소 공간  (1) 2021.08.08
3. 인터럽트 (Interrupt)  (1) 2021.08.08
2. 커널 (Kernel)  (0) 2021.08.06

1. IPC (Inter-Process Communication)

프로세스 간 통신하는 방법 2가지

1) 공유 메모리 사용 (Shared-Memory)

  • 버퍼를 shared-memory로 만들면 된다 → Shared Buffer
  • 생산자 - Buffer - 소비자
  • buffer 가득차면 Producer: waiting / buffer 비면 Consumer: waiting
  • 문제 상황
    • 성능이 좋지만 동기화 문제 발생
    • 응용 프로그래머가 다 해결해야 함 → 너무 복잡
  • 문제 해결 : Message-Passing 으로!!

2) Message-Passing

  • send(message), receive(message) system call로 OS가 해결
  • ex. pipes
  • communication link를 구현

 

2. Message-Passing

direct vs indirect

1) direct

  • send(P, message) - p에게 메시지 전송, receive(Q, message) - Q로부터 메시지 수신
  • 링크가 automatically 생성됨
  • 2개의 프로세스 간에 정확히 하나의 링크만 만들어짐 (1 : 1)

2) indirect

  • 뭔가 매개체가 필요함 - 매개체 = Port (mailbox)
  • 그냥 port로 전송만 하면 됨
  • 복잡한 Communication link를 만들 수 있음 (다 : 다)
  • 여기서 또 blocking I/O vs non-blocking I/O으로 나누어짐

 

3. 실제 IPC 예시

1) Shared Memory : POSIX Shared Memory

  • POSIX: Portable OS Interface (for UNIX)
  • memory-mapped files 사용
  • 문제 : 일일이 shm_open, write, read, close 등을 프로그래머가 다 해줘야 함
  • 좀 더 진화된 형태 : pipes

2) Message Passing : Pipes

  • 생산자-소비자 방식으로 두 개의 프로세스가 서로 통신하는 메커니즘
  • uni-direction (단방향) vs bi-direction(양방향)
  • half-duplex(송, 수신 중 한 번에 하나만 가능) vs full-duplex (양방향으로 동시에 송수신)
  • 전통적인 pipe = 단방향 통신 2개 만들어 양방향처럼 사용하면 됨
  • 문제 : 그럼 Client-Server System에서는??
    • 네트워크 내에서 다른 2개의 컴퓨터끼리 shared memory 및 pipe 연결 불가능!!
  • 해결 : socket

 

4. Communication in Client-Server Systems

Pipe → Socket → RPC

1) Sockets

  • IP addr + Port = Socket
  • 네트워크 상의 서로 다른 endpoint 끼리의 통신할 때
  • Java
    • Socket class: connection-oriented (TCP)
    • DatagramSOcket class: connectionless (UDP)
    • MulticastSocket class: multiple recipients

2. RPCs (Remote Procedure Calls)

  • remote host에 있는 procedure를 호출하겠다.
  • marshaling 한 파라미터를 서로 넘겨줌 (쉽게, server, client 간에 넘겨줄 parameter 형식 맞춰준다고 생각)
    ex. serialization
  • IPC의 확장 개념

 

 

1. 스레드란?

  • 프로세스가 할당받은 자원을 이용하는 실행 흐름의 단위.
  • 공유 자원 : 주소 공간, Code, Data, Heap, 열린 파일, 신호
  • 별도 자원 : register와 Stack
  • 자원의 생성과 관리의 중복성을 최소화하여 수행 능력을 향상
  • 한 스레드의 결과가 다른 스레드에 영향을 끼친다.

User-level thread

  • 장점 : 빠르다
  • system call이나 I/O 가 발생해서 Block 되면, 프로세스 자체가 block 되었다고 판단하여, 다른 스레드도 돌릴 수 없다. → CPU 안 쓰게 된다.
  • 무한 루프 돌고 있어서 자원을 계속 차지하고 있어도, 뺏어올 수 없음 → 자발적으로 넘겨줘야 함

Kernel-level thread

  • 단점 : 느리다.
  • OS 가 알아서 thread 가 block 되면 다른 thread로 CPU를 할당함

 

2. 멀티 스레드

  • 멀티 스레드를 제공한다면, CPU를 점유하는 가장 작은 단위 = 스레드가 됨
  • 즉, Parallel 한 작업
  • 한 개의 단일 애플리케이션은 여러 스레드로 구성 후 작업 처리해야 한다.
  • 한글에서 싱글 스레드를 사용하면, 프린트를 하는 경우 문서 수정은 불가능하다.
  • 디버깅이 어렵다. 자원 공유 문제(교착상태)가 생긴다.

우리가 컴퓨터 살 때 보는 '6 코어 12 스레드'에서 스레드는 물리적인 코어 6개로 12개의 스레드를 동시 멀티스레딩(SMT, Simultaneous Multi-Threading)으로 구현이 된 것이라고 한다 (하이퍼스레딩이 있는 CPU라고 한다). 즉 S/W의 관점으로는 하나의 코어에 하나의 가상의 코어를 만들어서 CPU 2개로 인식된다. 

 

즉, 물리적인 Core 위에 하이퍼스레딩으로 구현된 (물리적이라고 볼 수 있는) Core 스레드가 여러 개 존재하고, 그 위로 Kernel-level 스레드가 더 여러개 있을 수 있고, 그 위로는 User-level 스레드가 더더 여러개 있을 수 있는 구조가 되겠다. (물론 어떤 멀티 스레드 모델이냐에 따라 다를 수 있다.)

멀티 스레드 모델

 

 

3. Context-Switching : 프로세스 vs 스레드

  • 프로세스는 운영체제로부터 자원을 할당받아 실행하고, 스레드는 프로세스로부터 자원을 할당받아 실행합니다.
  • 프로세스 : fork()를 통해 생성되는데, 매번 동일한 코드가 복사되어 작동하고, PCB, 주소 복사 등 Context Switching에 Cost가 크다.
  • 스레드 : 레지스터와 스택을 제외하고 자원을 공유하여 사용 → 한 가지 스레드는 I/O를 담당하는 등, 스레드로 각 CPU에 일을 할당해서 수행 가능

 

 

4. 멀티 프로세스 vs 멀티 스레드

1. 멀티 프로세스

  • Concurrency 한 작업

 

2. 멀티 스레드

  1. 멀티 프로세스보다 자원을 효율적으로 사용 가능
    • 멀티 프로세스로 실행하던 작업을 멀티 스레드로 실행하면, 프로세스를 생성하여, 자원을 할당하는 시스템 콜이 줄어든다
    • 메모리를 공유하기 때문에, 프로세스 간 통신 방법에 비해 스레드 간의 통신 방법이 간단하다.
  2. 처리 비용 및 응답 시간 단축
    • context-switching 시 발생하는 오버헤드를 감소시킬 수 있다.
    • 심지어 스레드의 context switch는 프로세스 context switch 와는 달리 캐시 메모리를 비울 필요가 없다.
  3. 문제점
    • 멀티 프로세스 기반으로 프로그래밍할 때는 프로세스 간 공유하는 자원이 없기 때문에 동일한 자원에 동시에 접근하는 일이 없었지만 멀티 스레딩을 기반으로 프로그래밍할 때는 이 부분을 신경 써줘야 한다. 서로 다른 스레드가 데이터와 힙 영역을 공유하기 때문에 어떤 스레드가 다른 스레드에서 사용 중인 변수나 자료구조에 접근하여 엉뚱한 값을 읽어오거나 수정할 수 있다.
  4. 해결
    • 멀티스레딩 환경에서는 동기화 작업이 필요하다. 동기화를 통해 작업 처리 순서를 컨트롤하고 공유 자원에 대한 접근을 컨트롤하는 것이다. 하지만 이로 인해 병목현상이 발생하여 성능이 저하될 가능성이 높다. 그러므로 과도한 락으로 인한 병목현상을 줄여야 한다.

 

5. Thread 관련 예시

(질문1) 워드에서 글자를 입력했을 때 어떤 일이 발생하는가?

  • 사용자 입력 → 외부 Interrupt 중 I/O Interrupt 발생 → CPU 인지 → CPU 작업 중이던 상태 저장 → 해당 인터럽트 처리 → 상태 복구 및 중단되었던 작업 재개

개인적으론 이 질문이 크롬에 사이트 url을 입력했을 때 일어나는 일을 설명해보라는 질문과 동급이라고 생각한다. 이 질문에 대해 대부분의 글들에선 위처럼 단순히 Interrupt에 대해서만 설명하고, 그대로 복사해오는 것 같아서 나름대로 깊게 생각을 해보았다. 

  • 우선 내 생각은 워드라는 프로세스는 멀티 스레드로 구현이 되어있다고 생각이든다.
  • 그렇게 생각한 이유는 커서가 깜박이고, 입출력을 행할 때 다른 행동을 동시에 할 수 있기 때문이다.
  • 따라서 I/O를 처리할 스레드를 만들었을 것이고, 해당 스레드에서 I/O 인터럽트가 걸릴 것이라 생각이 된다.
  • 헌데 I/O 인터럽트가 걸렸다고 해서 해당 프로세스가 통째로 blocked 되지는 않으므로 하나의 커널 스레드만 사용 중인 것은 아닐 것 같다.
  • 즉, 1:1 혹은 m:n으로 스레드 매핑이 이루어져 있을 것 같다.
  • 인터럽트가 발생한 스레드는 이후 인터럽트 처리 과정이 이루어질 것이다.
  • 실행 중이던 스레드가 실행이 중단되고, TCB에 context를 저장한 후, 인터럽트 원인을 판별 -> 인터럽트 벡터 테이블을 참조 -> ISR(인터럽트 서비스 루틴) 처리 -> Interrupt 처리 종료 후 ready 큐에 있는 작업을 실행하면서 상태를 복구할 것 같다.
  • 이후에 화면에 출력해주는 Interrupt가 걸려서, 또다시 같은 과정을 통해 화면에 그려줄 것으로 예상된다.

이후에 더 공부하면서 추가/수정 한 부분

  • 워드 프로세서는 3가지의 스레드를 가진다
    1. interactive 스레드
    2. Reformatting 스레드
    3. Disk-backup 스레드
  • DMA를 이용하여 I/O를 모아서 처리한다.
    • 출력하려면 마지막에 CPU가 인터럽트를 받아서 출력장치에 값을 넘겨줘야 한다.
    • 이때 문제는 한 글자가 4개 블락으로 돼있으면 한 블락당 검사를 해서 4번의 인터럽트가 걸린다고 볼 수 있는데
    • DMA가 이 검사를 대신해줘서 CPU는 한 번의 인터럽트만 받게 된다!
  • 모니터에 화면을 보여주는 것을 계속 I/O Interrupt 가 발생할까?
    • 화면 출력도 프린터 출력하는 거랑 비슷하게 cpu 거쳐가서 커널 스레드가 하드웨어한테 작업을 부여해줄 뿐 실질적인 출력 실행에는 cpu가 쓰이지 않는다.


(질문2) Chrome 은 멀티 프로세스일까? 멀티 스레드 일까?

이에 대한 정말 정확하고 명쾌한 설명이 담긴 아티클을 첨부하겠다

https://d2.naver.com/helloworld/2922312

 

 

 

Reference

- https://d2.naver.com/helloworld/2922312

프로세스의 주소 공간

Code, Data, BSS, Heap, Stack

 

코드 (Code / Text)

  • 작성한 코드가 기계어 명령으로 변환되어 저장되는 영역
  • 이 부분은 컴파일 후에 바뀌지 않으므로 같은 프로그램에서 이 코드 부분을 공유하여 메모리 사용량을 줄이기 위해 존재

데이터 (Data)

  • 초기화된 전역 변수, 정적 변수와 배열, 구조체가 존재,
  • 프로그램 실행 시 생성, 종료 시 반환,
  • 함수 내부 정적 변수는 프로그램 실행 시 공간만 할당하고 함수 실행 시 초기화

BSS (Block Stated Symbol)

  • 초기화되지 않은 데이터 저장

힙 (Heap)

  • 동적 할당 (malloc, new)된 데이터가 저장, 런타임에 크기가 결정,
  • 힙 영역에 할당한 다 쓴 메모리를 반환하지 않으면 메모리가 부족해지는 것을 ‘메모리 누수’

스택 (Stack)

  • 임시 메모리 영역으로 지역 변수, 매개 변수, 반환 값 등이 잠시 저장, 함수의 호출이 끝나고 돌아갈 반환 주소, 함수 내의 지역 변수 등이 저장되는 정보를 ‘스택 프레임’이라고 함
  • 런타임에 크기가 결정되지만, 런타임에 스택의 총 사이즈를 변경 못함

추가 정보

  • 코드,데이터,스텍 영역은 컴파일러가 결정, 힙은 개발자가 결정
  • 스택은 상위 메모리부터 할당, 나머지는 하위 메모리부터 할당

오버플로우

  • heap overflow : heap이 주소 값을 채우며 내려오다가 stack 영역을 침범
  • stack overflow : stack이 밑에서부터 주소 값을 채우며 올라오다가 heap 영역을 침범

 

프로세스의 주소 공간

 

 

Reference

[동적 할당- 런타임, 컴파일 할당] 

 

'CS > 운영체제 (OS)' 카테고리의 다른 글

8. IPC (Inter-Process Communication)  (0) 2021.08.11
7. 프로세스 vs 스레드  (0) 2021.08.11
3. 인터럽트 (Interrupt)  (1) 2021.08.08
2. 커널 (Kernel)  (0) 2021.08.06
1. 운영체제 (OS) & 부팅과정  (0) 2021.08.06

개요

그동안 학교에서 배웠던 내용 + 전공책을 뒤져가며 공부했던 내용 + 취준 하면서 복습했던 내용들을 정리하는 목적으로 작성하였습니다.

 

1. 인터럽트(Interrupt) 란?

Interrupt는 프로그램 실행 중에 CPU의 현재 처리 순서를 중단하고, 다른 동작을 수행하도록 요구하는 것이라고 볼 수 있다. 즉, Interrupt가 발생하면 운영체제는 CPU에게 그동안 하고 있는 일들을 멈추고, Interrupt를 해결하도록 한다.

 

Interrupt가 발생하게 되면, ISR (Interrupt Service Routines)이라는 것이 실행되는데, 이를 인터럽트 핸들러(Interrupt Handler)라고도 한다

 

그렇다면 Interrupt는 어떤 때에 발생하는 것일까? Interrupt는 예외상황에 대한 처리가 필요한 상황에 발생한다. 예외상황에 따라 Interrup는 크게 (1) 외부 Interrupt, (2) 내부 Interrupt, (3) SW Interrupt로 나눌 수 있다.

 

 

1. 외부 Interrupt

외부 Interrupt는 CPU 코어 외부 요인으로 발생하는 것을 말하는데, 전기적인 신호로 CPU에게 Interrupt를 거는 경우로 (1) 전원 이상 Interrupt, (2) I/O Interrupt, (3) 타이머 Interrupt 같은 것들이 있다.

  1. 전원 이상 Interrupt의 경우,
    • 갑자기 전원 공급이 중단되는 경우 CPU에 Interrupt를 걸어 작업 중이던 프로세스를 대피시킬 수 있도록 한다.
  2. I/O Interrupt의 경우,
    • CPU가 I/O 장치 (키보드, 마우스, 프린터 등) 에게 일을 맡기거나, I/O 장치가 CPU에게 정보를 전달해 줄 때 호출된다.
  3. 타이머 Interrupt의 경우,
    • 컴퓨터 내부의 타이머가 CPU에 주기적으로 expired 되었다고 알림을 주는데, 이것이 Interrupt이다. 따라서 하나의 프로그램이 CPU 자원을 너무 오랫동안 점유하지 못하도록 한다. 또한 무한루프가 도는 프로그램도 이 덕분에 종료되고 Context Switch가 발생할 수 있다.
    • (참고) 타이머 Interrupt는 100hz로 인터럽트를 건다. 즉, 10ms 마다 interrupt가 걸린다.

 

 

2. 내부 Interrupt

내부 Interrupt는 CPU 코어 내부에서 프로그램이 실행되면서 Interrupt에 걸리는 경우로 프로그램 검사 인터럽트(Program check interrupt)이다. Exception Interrupt, 혹은 Trap이라고 부른다.  

  • Exception Interrupt (Trap
    • Division by zero
    • Overflow/Underflow
    • 기타 프로그램 Exception

Exception이라는 것은, 결국 예외상황에 대한 의미로, 소프트웨어 내부에서 예외상황을 처리하는 것을 두고 소프트웨어 Interrupt를 Exception으로 보는 경우도 있다. 

 

Trap의 의미는, 특별한 조건을 걸어두고 조건에 부합하는 경우 상황에 맞는 Service Routine이나 Handler 가 실행되도록 하는 것을 의미한다. 따라서 이 경우에는 ISR (Interrupt Service Routines) 혹은 인터럽트 핸들러(Interrupt Handler)가 되겠다.

 

Exception과 Trap 은 프로그래밍 전반적으로도 사용되는 용어이니, 결국은 단어를 어떻게 해석하느냐의 차이인 것 같다. 결국 너무 단어에 매몰되지 말고, 개념을 잘 익히는 것이 중요하다.

 

 

3. 소프트웨어 Interrupt

소프트웨어 Interrupt는 프로그램 처리 중 명령의 요청에 의해서 발생하는 경우로 SVC (SuperVisor Call) 이 있다.

  • SVC (SuperVisor Call)

일반적인 응용 프로그램은 User Mode에서 실행이 되는데, 이 경우 직접 접근할 수 있는 자원에 제한이 있다. 예를 들어 어떤 프로그램이 컴퓨터에 대한 통제권을 갖는 코드를 갖고 있다고 할 때, 이런 것이 허락도 없이 수행될 수는 없는 것이다. 즉, 이러한 자원에 접근하는 명령어는 Supervisor 만 실행할 수 있어야 하고, 이것이 즉, Kernel Mode가 되는 것이다. 즉, 응용프로그램은 SuperVisor Call을 통해 허락을 맡은 후 Supervisor Mode (=Kernel Mode)로 변경하고, 해당 명령을 실행 후, 다시 User Mode로 변경하는 과정을 거치게 된다.

 

운영체제가 제공하는 서비스에 대한 프로그래밍 인터페이스가 System Call이고, System Call을 실행시키기 위한 CPU 명령어가 SVC이다.

 

 

 

2. 인터럽트 처리 과정

요청 → 중단 → 보관 → 인터럽트 처리 → 재개

  1. 인터럽트 요청
  2. 프로그램 실행 중단
    • 현재 실행 중이던 Micro Operation까지 수행
  3. 현재 실행 중인 프로그램 상태 보관
    • PCB(Process Control Block), PC(Program Counter) 저장
  4. 인터럽트 원인 판별
    • 인터럽트를 요청한 장치를 식별 → 인터럽트의 원인을 파악 
    • Interrupt Vector 테이블을 참조하여 호출할 ISR (인터럽트 서비스 루틴)  주소 값을 얻음
  5. ISR (인터럽트 서비스 루틴) 처리
    • 실질적인 인터럽트 처리 작업을 한다.
    • 서비스 루틴 수행 중, 우선순위가 더 높은 인터럽트가 발생하면 재귀적으로 1~5 과정 수행한다
    • 인터럽트 서비스 루틴을 실행할 때 인터럽트 플래그(IF)를 0으로 하면 인터럽트 발생을 방지할 수 있다.
  6. 상태 복구
    • 상태 복구 명령어가 실행되면, 저장해둔 PC(Program counter)를 다시 복원하여 이전 실행 위치로 복원한다.
  7. 중단된 프로그램 실행 재개
    • PCB의 값을 이용하여 이전에 수행 중이던 프로그램을 재개한다.

 

 

3. Interrupt 관련 예시

(질문) 구글 검색창을 클릭 후 빈칸에 커서가 깜빡이고 있다. 이때 hello world를 작성하면 컴퓨터 내부에서 어떤 일이 발생하는가?

  • 사용자 입력 → 외부 Interrupt 중 I/O Interrupt 발생 → CPU 인지 → CPU 작업 중이던 상태 저장 → 해당 인터럽트 처리 → 상태 복구 및 중단되었던 작업 재개

 

 

질문

인터럽트와 시스템 콜의 차이에 대해서 설명하세요.

더보기

Interrupt

  • Interrupt는 프로그램 실행 중에 CPU의 현재 처리 순서를 중단하고, 다른 동작을 수행하도록 요구하는 것이라고 볼 수 있다.
  • 즉, Interrupt가 발생하면 운영체제는 CPU에게 그동안 하고 있는 일들을 멈추고, Interrupt를 해결하도록 한다.

System Call

  • 운영체제가 제공하는 서비스에 대한 프로그래밍 인터페이스가 System Call이고, System Call을 실행시키기 위한 CPU 명령어가 SVC이다.

 

 

Reference.

[인터럽트] https://jhnyang.tistory.com/167

[인터럽트] https://hibee.tistory.com/264

[SVC vs System Call] https://www.techopedia.com/definition/25808/supervisor-call

'CS > 운영체제 (OS)' 카테고리의 다른 글

8. IPC (Inter-Process Communication)  (0) 2021.08.11
7. 프로세스 vs 스레드  (0) 2021.08.11
4. 프로세스의 주소 공간  (1) 2021.08.08
2. 커널 (Kernel)  (0) 2021.08.06
1. 운영체제 (OS) & 부팅과정  (0) 2021.08.06

1. 커널 (Kernel) 이란?

커널은 운영체제(OS)의 주요 구성 요소이며 컴퓨터 하드웨어와 프로세스를 잇는 핵심 인터페이스이다.

커널이라는 이름은 단단한 껍질 안의 씨앗처럼 OS 내에 위치하고 전화기, 노트북, 서버 또는 컴퓨터 유형에 관계없이 하드웨어의 모든 주요 기능을 제어하기 때문에 붙은 이름이다.

 

 

2. 커널의 기능

1) 메모리 관리: 메모리가 어디에서 무엇을 저장하는 데 얼마나 사용되는지를 추적합니다.

2) 프로세스 관리: 어느 프로세스가 중앙 처리 장치(CPU)를 언제 얼마나 오랫동안 사용할지를 결정합니다.

3) 장치 드라이버: 하드웨어와 프로세스 사이에서 중재자/인터프리터의 역할을 수행합니다.

4) 시스템 호출 및 보안: 프로세스의 서비스 요청을 수신합니다.

 

 

3. 이중 실행 모드 (Kernel mode vs User mode)

Kernel mode와 User mode에 대해 살펴보기 전에, 이를 나눈 근본적인 이유가 상당히 중요하다.

응용 프로그램이 시스템 자원에 직접 접근하게 되면 심각한 오류들을 유발할 수 있기 때문에, 각 응용 프로그램이 시스템 자원에 직접 접근하지 못하도록 하기 위해서 나누어 놓았다. 따라서, 자원에 대한 접근 권한은 커널에게만 부여하여, 자원에 대한 접근이 필요한 시점에는 System call을 통해서 간접적으로 실행하도록 하였다. 결국 자원에 대한 접근은 커널을 통해서만 접근할 수 있는 것이다.

 

1. 커널 모드 (Kernel mode / SuperVisor mode)

커널 모드에서 운영체제는 모든 하드웨어에 대한 완전한 접근이 가능하며, 기계가 실행할 수 있는 어떤 명령도 실행할 수 있다. 즉, Kernel mode는 운영체제가 CPU의 제어권을 가지고 명령을 수행하는 모드로 일반 명령과 특권 명령 모두 수행할 수 있다. 또한 모든 주소 공간에 접근이 가능하다.

 

2. 유저 모드 (User mode)

유저 모드 기계 명령 중 일부만을 실행할 수 있는 모드로, 특별히 기계의 제어에 영향을 미치거나 I/O를 하는 명령들은 사용자 모드에서 실행할 수 없다. 즉, User mode는 일반 사용자 프로그램이 CPU 제어권을 가지고 명령을 수행하는 모드이기 때문에 일반 명령만을 수행할 수 있다. 또한 사용자 주소 공간만 접근이 가능하다.

 

운영체제 구조

 

4. 일반/특권 명령

CPU가 수행하는 명령에는 2가지 명령이 있는데, 명령을 다음과 같이 구분하여 부적절한 사용을 막는다.

 

일반 명령은 메모리에서 자료를 읽어와 CPU에서 계산하고 결과를 메모리에 쓰는 등의 명령이고, 모든 프로그램이 수행할 수 있는 명령이다. 따라서 사용자 응용 프로그램은 특권 명령을 사용하지 못합니다.

 

특권 명령은 프로세스 제어, 파일 조작, 장치(I/O, 타이머 등) 조작, 정보 유지 보수, 통신, 보호 등의 명령으로, 항상 운영체제에서만 수행할 수 있으며, 특권 명령을 사용하고 싶을 때 사용하는 것이 바로 '시스템 콜'이며 OS에게 특권 명령을 대신 실행해달라고 요청하는 것입니다.

 

5. 논리 주소 공간

1. 사용자 주소 공간 (User space)

  • 각 응용 프로그램이 나누어 적재되고 사용되는 공간

2. 커널 주소 공간 (Kernel space)

  • 커널에 의해 배타적으로 사용 - 커널 코드, 커널 데이터, 디바이스 드라이버 등

 

커널

 

6. 커널과 관련된 Issue

1. 커널은 스스로 실행되는 프로세스인가?

  • X, 시스템 호출을 통해 호출되는 단순 함수/데이터의 집합

2. 커널은 실행 중이다?

  • X, 시스템 호출/인터럽트를 통해 커널 코드/ISR이 실행되고 있을 뿐이다. (능동적인 주체 x, 수동적인 대상 o)

3. 커널은 스택이나 힙을 갖는가?

  • X, 각 프로세스/스레드가 스택/힙 소유
    • app이 커널 코드 실행 시, 커널 공간에 커널 코드 실행을 위한 스택 생성, 복귀 시 해제
  • 커널은 하나의 프로세스가 아니므로 그 자신만의 스택/힙을 갖지 않는다. 사용자 프로그램이 시스템 호출을 통해 간접적으로 커널 함수를 호출하게 되면, 현재 커널 코드의 실행을 위해 커널 영역에 stack이 임시로 생성이 될 수는 있다. 하지만 이는 커널이 관리하는 것이 아니라, 사용자 프로그램의 요청을 처리하기 위해 임시로 만들어진 stack/heap 에 불과하다. 따라서 시스템 호출을 마무리하고 복귀하면 없어진다.

 

 

Reference

[커널] https://www.redhat.com/ko/topics/linux/what-is-the-linux-kernel

[Modern Operating Systems 3rd]

 

'CS > 운영체제 (OS)' 카테고리의 다른 글

8. IPC (Inter-Process Communication)  (0) 2021.08.11
7. 프로세스 vs 스레드  (0) 2021.08.11
4. 프로세스의 주소 공간  (1) 2021.08.08
3. 인터럽트 (Interrupt)  (1) 2021.08.08
1. 운영체제 (OS) & 부팅과정  (0) 2021.08.06

개요

그동안 학교에서 배웠던 내용 + 전공책을 뒤져가며 공부했던 내용 + 취준 하면서 복습했던 내용들을 정리하는 목적으로 작성하였습니다.

 

1. 운영체제(OS) 란?

시스템의 자원과 동작을 관리하는 소프트웨어다.

  • 자원? CPU, memory, file, I/O

 

 

2. 운영체제의 기능

'커널 모드에서 실행하는 소프트웨어'로 크게 2가지 기능을 제공

  1. 하드웨어와 응용 프로그램의 매개로 아름답고 일관된 인터페이스로 제공한다. (사용자 관점)
  2. 하드웨어의 자원들을 공정하게 할당 및 관리한다. (시스템 관점)

 

 

3. 부팅 시 운영체제 실행 과정

1. BIOS(Basic Input Output System)

제일 먼저 CPU가 ON 되고, CPU는 ROM(비휘발성 메모리)에 있는 BIOS(Basic Input Output System) 데이터를 읽어온다.

 

2. POST(Power on self test)

BIOS는 POST(Power on self test)를 진행하여 하드웨어의 정상적인 작동을 검사한다.

부팅: 1.BIOS & 2.POST

3. 부트스트랩(Bootstrap)

POST에 이상이 없으면 BIOS는 부트스트랩을 실행하여 부팅 정보를 메모리로 읽어 온다.

  • 부트스트랩 : Disk의 MBR에 저장된 부팅 정보를 RAM(메모리)으로 읽어온다.
  • MBR(Master Boot Record): Disk의 첫 번째 섹터

4. 부트로더(Bootloader)

"운영체제(Boot)를 메모리로 읽어오는 역할(loader)"

부트로더는 Disk에 있는 운영체제(OS) 코드를 메모리로 읽어 온다. 즉, 앞에서 읽어온 부팅 정보는 부트로더(Bootloader)이다. 운영체제는 메모리에 상주하지 않지만 커널은 메모리에 상주한다.

부팅: 3.부트스츠랩 & 4.부트로더

5. 운영체제(OS) 실행

읽어 온 운영체제 명령에 의해 CPU는 첫 프로세스(Demon)를 즉시 실행한다.

이후, 인터럽트가 발생하면 CPU는 각종 작업을 처리한다.

부팅: 5. 운영체제 읽어옴

 

 

 

Reference

[부팅 과정] https://neos518.tistory.com/113

[Modern Operating Systems 3rd] 

'CS > 운영체제 (OS)' 카테고리의 다른 글

8. IPC (Inter-Process Communication)  (0) 2021.08.11
7. 프로세스 vs 스레드  (0) 2021.08.11
4. 프로세스의 주소 공간  (1) 2021.08.08
3. 인터럽트 (Interrupt)  (1) 2021.08.08
2. 커널 (Kernel)  (0) 2021.08.06

+ Recent posts