1.2.1 프로세스와 스레드
프로세스
컴퓨터에서 실행 중인 하나의 프로그램을 의미
- 프로그램은 특정 작업을 수행하기 위한 명령어의 집합
- OS는 프로그램을 실행하면서 디스크에 저장된 데이터를 메모리로 로드한다.
- 프로세스는 독립된 메모리 영역을 할당받고, 다른 프로세스의 메모리 영역에는 접근 불가능하다.
💡 프로세스의 메모리 영역 구조
- 스택(stack)
지역변수, 함수의 매개 변수, 반환되는 주소 값 등이 저장되는 영역
영역 크기는 컴파일 때 결정된다.
LIFO(후입선출) : 높은 주소 값에서 낮은 주소 값으로 메모리가 할당 - 힙(heap)
사용자에 의해 동적 메모리 할당이 일어나는 영역
영역 크기는 런타임 때 결정된다.
FIFO(선입선출) : 낮은 주소 값에서 높은 주소값으로 메모리가 할당 - 데이터(data)
전역 변수, 정적 변수, 배열, 구조체 등이 저장된다.
BBS영역(초기화되지 않은 변수 저장)과 데이터 영역(초기화한 변수 저장)으로 나뉜다. - 코드(code, 텍스트 영역)
실행할 코드가 기계어로 컴파일되어 저장되는 영역
☝🏻 메모리 공간을 공유하기 때문에 스택과 힙이 동적 메모리를 할당하다가 서로의 영역을 침범할 수 있다.
힙 영역이 스택 영역을 침범할 경우 : 힙 오버플로
스택 영역이 힙 영역을 침범할 경우 : 스택 오버플로
스레드
프로세스에서 실제로 실행되는 흐름의 단위
- 프로세스는 한 개 이상의 스레드를 가진다.
- 프로세스 내에 존재하기 때문에 프로세스의 메모리 공간을 이용하며, 독립적인 스택 영역(지역변수 저장)을 할당 받는다.
💡 프로세스의 메모리 영역 구조
1.2.2 PCB
프로세스를 제어하기 위해 프로세스 정보를 저장하는 프로세스 제어 블록(Process Control Block, PCB)
💡 PCB에 저장되는 정보 - PCB는 운영체제 영역에 저장된다.
- 프로세스의 현재 상태
- 프로세스를 나타내는 고유의 PID(Process ID)
- 부모 프로세스의 PID, 자식 프로세스의 PID
- 다음 실행할 명령어의 주소인 PC
- 프로세스의 우선순위
- 메모리 제한 등등....
1.2.3 프로세스의 생성
새로운 프로세스는 기존 프로세스에서 fork()함수(함수를 호출한 프로세스를 복사)를 호출해서 생성한다.
- 기존 프로세스 : 부모 프로세스
-> fork()함수를 호출했을 때 자식 프로세스의 PID값을 반환한다. - 복사된 프로세스 : 자식 프로세스
-> 부모가 fork()함수를 호출하면 0을 반환한다.
즉 반환되는 값이 두 개..?
⏬ 운영체제가 프로세스를 종료하는 경우
📖 운영체제가 프로세스를 종료하는 경우
- 프로세스가 exit() : 운영체제의 종료 서비스를 호출하는 경우 -> 정상 종료
- 프로세스의 실행 시간, 특정 이벤트 발생을 기다리는 시간이 제한된 시간을 초과한 경우 : 시간 초과
- 프로세스가 파일 검색, 입출력을 실패하는 경우
- 오류 발생, 메모리 부족
📖 부모 프로세스가 자식 프로세스를 종료시킬 수 있는 경우
- 자식 프로세스가 할당된 자원을 초과할 때
- 자식 프로세스에 할당된 자원이 없을 때
1.2.4 프로세스 상태도
모든 프로세스는 CPU에 의해 생성되고 소멸되는 과정을 거친다.
- 생성(new) : 프로세스가 PCB를 가지고있지만 OS로부터 승인받기 전
- 준비(ready) : OS로부터 승인받고 준비 큐에서 CPU할당을 기다림 -> CPU빼고 다른 자원이 준비됨
- 실행(running) : 프로세스가 CPU를 할당받아 실행함 -> 우선순위가 높은 프로세스가 디스패치 됨
- 대기(waiting) : 입출력이나 이벤트 발생을 기다려야해서 CPU사용을 멈추고 기다림
- 종료(terminated) : 프로세스 실행 종료
☝🏻 실행 -> 준비
한 프로세스가 무한히 CPU를 독점하는 것을 방지한다.
여러 프로세스가 빠르게 번갈아가며 실행되어 사용자에게 동시에 실행되는 것처럼 보이는 효과를 제공.
☝🏻 디스패치(Dispatch)
프로세스에 CPU 자원을 할당해 해당 프로세스가 준비 상태에서 실행 상태가 되는 것
1.2.5 멀티 프로세스와 멀티 스레드
동시성(Concurrency)
하나의 코어(싱글 코어)에서 여러 작업을 번갈아 가면서 처리하는 방식
- CPU는 한 번에 하나의 작업만 실행할 수 있어 여러 작업을 돌아가면서 처리한다.
- 이렇게 처리중인 작업을 교체하는 것이 콘텍스트 스위칭이다.
병렬성(Parallelism)
CPU가 여러 개(멀티 코어) 있어서 각 CPU에서 각 작업을 동시에 처리한다.
멀티 프로세스
응용 프로그램 하나를 어러 프로세스로 구성
- 한 프로세스가 죽어도 다른 프로세스에 영향을 주지않아 안정적이다.
- 시간과 메모리 공간을 많이 사용한다는 단점이 있다.
- CPU가 여러 프로세스를 처리하려면 콘텍스트 스위칭 작업이 이루어져야한다.
이때 프로세스를 교체하면서 메모리 영역을 다른 프로세스에서 사용할 수 있도록 하면서 시간과 메모리가 필요하다.
이 시간과 메모리를 오버헤드라고 한다. - 프로세스는 독립적인 메모리를 할당받는다.
만약 프로세스 간에 공유할 지원이 있다면 IPC를 통해 프로세스 간에 자원을 공유해야한다.
직접 자원에 참조하는 것보다 비효율적!
멀티 스레드
프로세스 내에 스레드를 여러 개 생성하여 스레드들이 각자 다른 작업을 처리하는 것
- 스레드 간에 힙, 데이터, 코드 영역을 공유한다. 때문에 IPC를 사용할 필요가 없다.
- 프로세스 간 자원 공유보다 스레드 간 자원 공유가 시스템 처리 비용도 적고 프로그램 응답 시간도 단축된다.
- 콘텍스트 스위칭할 때 오버헤드가 적다. (힙, 데이터, 코드 영역을 공유하기 때문에)
- 스택 영역을 다른 스레드와 함께 사용하므로 공유 자원에 대한 동기화가 필수다.(독립된 스택 영역을 가지고 실행하기 때문)
- 스레드에 문제가 생기면 프로세스 내 다른 스레드에 영향을 줄 수 있다.
1.2.6 콘텍스트 스위칭
인터럽트
CPU에서 프로세스를 처리하다가 입출력 관련 이벤트가 발생하거나 예외 상황이 발생할 때 이에 대응할 수 있도록 CPU에 처리를 요청하는 것
💡 인터럽트가 발생하는 경우
- 입출력이 발생할 때
- CPU 사용 시간이 만료
- 자식 프로세스 생성할 때
이렇게 인터럽트가 발생하면서 콘텍스트 스위칭이 일어난다.
콘텍스트 스위칭
멀티 프로세스 환경에서 인터럽트로 인해 CPU가 처리 중인 프로세스의 정보를 바꾸는 것
- P1(프로세스 1)이 실행 중
- P1 인터럽트 또는 시스템 콜 발생 -> P1의 실행 중단
- P1의 상태 저장 -> P1의 작업 상태를 PCB에 저장(P1이 다시 실행될 때 복구된다.)
- P2의 상태 로드 -> 준비 상태에 있던 P2의 PCB에 저장된 정보가 CPU에 로드
- P2가 CPU를 사용해 작업을 실행
- P2 인터럽트 또는 시스템 콜 발생 -> P2 작업 중단
- P2의 상태 저장 및 P1의 상태 로드
☝🏻 유휴 상태(idle)
CPU가 현재 실행 중인 프로세스를 중단하고 다음 프로세스를 준비하는 동안 실제로는 어떤 작업도 수행하지 않는 상태
💡 PCB에는 프로그램 카운터와 스택 포인터 값이 저장되어 있다.
☝🏻 프로그램 카운터
프로세스가 이어서 처리해야 하는 명령어의 주소 값.
즉, 다음에 실행해야 할 명령어의 위치를 저장하는 곳. 책의 책갈피와 같다.
☝🏻 스택 포인터
스택 영역에서 데이터가 채워진 가장 높은 주소값
즉, 스택에서 가장 마지막에 저장된 데이터의 위치를 저장하는 곳. 쌓인 접시 중 가장 위에 있는 접시
'[ STUDY ] > CS' 카테고리의 다른 글
[ 운영체제 ] 가상 메모리 - 요구 페이징, 스레싱 (0) | 2024.11.11 |
---|---|
[ 운영체제 ] 메모리 관리 전략 - 페이징, 세그먼테이션 (0) | 2024.11.11 |
[ 운영체제 ] 스케줄링 (0) | 2024.11.11 |
[ 운영체제 ] 프로세스 2️⃣ - 프로세스 동기화, 교착 상태, IPC, 좀비고아··· (2) | 2024.11.11 |
[ 운영체제 ] 운영체제 (1) | 2024.11.10 |