메모리 구조
코드 영역: 실행할 프로그램의 코드
데이터 영역: 전역 변수, 정적 변수
(프로그램 시작과 동시에 할당, 프로그램이 종료되어야 소멸)
힙 영역: 사용자의 동적 할당
스택 영역: 지역 변수, 매개 변수
(함수 호출 시 ! 함수 호출이 완료되면 사라짐)
프로세스 (Process)
: 메모리에 올라와 실행되고 있는 프로그램 (OS는 모든 프로그램을 프로세스 형태로 실행함)
- OS로 부터 독립된 영역을 할당 받음 (통신을 위해서는 IPC: Inter-Process Communication 사용)
- 프로세스는 최소 한개의 쓰레드 (메인 쓰레드)를 가짐
- new(생성), running(실행), waiting(I/O, event wait, waiting-> ready), ready(by interrupt), terminated(종료) 상태로 존재
프로세스 제어 블록(Process Control Block, PCB)
: 프로세스에 대한 중요한 정보를 저장 하고 있는 운영체제의 자료구조로,
context switching 상황을 대비해 다음과 같은 정보를 가지고 있다.
- 프로세스 식별자(Process ID, PID) : 프로세스 식별번호
- 프로세스 상태 : new, ready, running, waiting, terminated 등의 상태를 저장
- 프로그램 카운터 : 프로세스가 다음에 실행할 명령어의 주소
- CPU 레지스터
- CPU 스케쥴링 정보 : 프로세스의 우선순위, 스케줄 큐에 대한 포인터 등
- 메모리 관리 정보 : 페이지 테이블 또는 세그먼트 테이블 등과 같은 정보를 포함
- 입출력 상태 정보 : 프로세스에 할당된 입출력 장치들과 열린 파일 목록
- 어카운팅 정보 : 사용된 CPU 시간, 시간제한, 계정번호 등
* PCB는 Linked List 방식으로 관리하여 삽입/삭제가 용이하다!
멀티 프로세스
: 하나의 프로그램을 여러개의 프로세스로 구성하여 각 프로세스가 병렬적으로 작업을 수행하는 것
- 1개의 프로세스가 죽어도 자식 프로세스 이외의 다른 프로세스들은 계속 수행
- Context switching을 위한 overhead 발생
- 프로세스는 각각 독립된 메모리 영역을 받았기 때문에 통신이 어려움 ( → IPC 통신)
= 장점: 안전성 / 단점 : 오버헤드
스레드 (Thread)
: 프로세스 내에서 할당 받은 자원을 이용해 동작하는 실행 단위
= 프로세스 내 실행 단위
- 프로세스 내에 존재하며 프로세스가 할당 받은 자원을 이용해 실행
- 스레드 ID, 프로그램 카운터, 레지스터 집합, 스택으로 구성
- stack이 함수 호출 정보를 저장하기 때문에, 독립적인 실행 흐름을 위해 stack, pc register는 별도로 할당
- code, data, heap 영역은 공유
- 쓰레드는 프로세스의 자원을 공유하기 때문에 다른 쓰레드에 의한 결과를 즉시 확인 가능
멀티 스레드
: 하나의 프로그램을 여러개의 스레드로 구성하여 각 스레드가 1개의 작업을 처리하도록 하는 것
- 프로세스를 위해 자원을 할당하는 시스템콜이나 Context switching 등의 오버헤드 감소
- 메모리를 공유하기 때문에 통신이 쉽고, 자원을 효율적으로 사용 가능
- 하나의 스레드에 문제가 생기면, 전체 프로세스가 영향을 받음 (메모리를 공유 하므로)
- 여러 스레드가 하나의 자원에 동시에 접근하는 경우 자원 공유 문제가 발생 (동기화 중요)
= 장점: 자원 공유로 인한 시간, 메모리 등 오버헤드 감소 / 단점 : 안전성 문제 (Critical Section 기법을 통해 대비)
* Critical Section : 병렬컴퓨팅에서 둘 이상의 스레드가 동시에 접근해서는 안되는 공유 자원을 접근하는 코드의 일부
=> 상호 배제, 진행, 한정된 대기
Interrupt
: 프로그램을 실행하는 도중 예기치 않은 상황이 발생할 경우 현재 실행 중인 작업을 즉시 중단하고, 발생한 상황에 대한 우선 처리가 필요함을 CPU에 알리는 것
= 지금 수행 중인 일보다 더 중요한 일(ex. 입출력, 우선 순위 연산 등)이 발생하면 그 일을 먼저 처리하고 나서 하던 일을 계속 진행함
= 이 과정을 Context Switching이라고 부른다!
- 외부 Interrupt : 전원이상, 기계착오, 외부신호, 입출력 등 외부적인 요인으로 발생
- 내부 Interrupt (Trap) : 잘못된 명령이나 잘못된 데이터를 사용할때 발생 ex) Division by zero, Overflow/Underflow 등
- software Interrupt : 사용자가 프로그램을 실행시키거나 감시프로그램(Supervisor)을 호출할 때 발생
* Interrupt와 Pooling 의 차이
(공통점) Interrupt와 Pooling 모두 이벤트를 처리하는 방법
(차이점) Interrupt : 이벤트를 수행하라는 신호를 받으면 핸들러를 통해서 바로 이벤트를 수행하는 방식
Pooling : 이벤트를 수행하라는 신호를 받았는지 주기적으로 검사하면서 그 신호를 받았을때 이벤트를 실행하는 방식
Context Switching
: interrupt를 발생시켜 CPU에서 실행중인 프로세스를 중단하고, 다른 프로세스를 처리하기 위한 과정
Process 1 실행 중
↓ (ex. I/O interrupt)
Save state in PCB1 / Load state in PCB2
↓ (Process 1 다시 진행)
Save state in PCB2/ Load state in PCB1
- 어디까지 진행했는지? 다시 어디서부터 진행해야 하는지 등의 정보를 알 수 있도록 PCB를 사용하는 것!
- 프로세스는 독립된 메모리 영역을 할당받아 사용하므로, 캐시 메모리 초기화 같은 무거운 작업 시 오버헤드 발생
IPC(Inter Process Communication)
독립적 구조를 가진 프로세스 간의 통신 방법
1. 익명 PIPE (반이중 통신)
- 통신할 프로세스를 명확히 알 수 있는 경우에 사용 ex) 부모-자식 프로세스
- 하나의 프로세스는 데이터를 쓰기만 , 다른 프로세스는 데이터를 읽기만 할 수 있음
- 양쪽으로 모두 송/수신을 하고 싶으면 2개의 파이프를 만들어야 함
- 장점) 매우 간단하게 사용할 수 있고, 단순한 데이터 흐름을 가질 때 효율적
- 단점) 전이중 통신을 위해 2개를 만들어야 할 때는 구현이 복잡함
2. Named PIPE (FIFO)
- 전혀 모르는 상태의 프로세스들 사이 통신에 사용 (통신을 위해 이름있는 파일을 사용)
- 전이중 통신을 위해서는 익명 파이프처럼 2개를 만들어야 함
3. Message Queue
- 입출력 방식은 Named PIPE와 동일
- 메시지의 type에 따라 각 프로세스에게 필요로하는 메시지만 수신 가능
4. 공유 메모리
- 프로세스간 메모리 영역을 공유해서 사용할 수 있도록 허용
- 프로세스가 공유 메모리 할당을 커널에 요청하면, 이후 모든 프로세스는 해당 메모리 영역에 접근 가능
- 중개자 없이 곧바로 메모리에 접근할 수 있어서 IPC 중에 가장 빠르게 작동
5. 메모리 맵
- 공유 메모리처럼 메모리를 공유
- 열린 파일을 메모리에 맵핑시켜서 공유하는 방식 (즉 공유 매개체가 파일+메모리)
- 주로 파일로 대용량 데이터를 공유해야 할 때 사용
6. 소켓
- 클라이언트와 서버가 소켓을 통해서 통신하는 구조
- 원격에서 프로세스 간 데이터를 공유할 때 사용
'CS > 운영체제' 카테고리의 다른 글
Memory Management (메모리 관리 전략) (0) | 2023.04.24 |
---|---|
DeadLock (교착 상태) (0) | 2023.01.12 |
프로세스 동기화 (Synchronization) (0) | 2022.12.28 |
CPU Scheduling (0) | 2022.12.01 |
운영체제란? (0) | 2022.11.29 |