- 스터디 설명 : 에이블스쿨 교육생들과 CS 공부를 위해 자발적으로 개설 및 참여한 스터디입니다.
- 혼자 공부하는 컴퓨터 구조+운영체제를 교재로 사용하였고, 일부 내용은 별도의 자료로 공부하였습니다.
프로세스 개요
- 프로그램은 실행 전에는 그저 데이터 덩어리이지만, 메모리에 적재되고 실행되는 순간 프로세스가 된다. 이 과정을 프로세스를 생성한다고 표현한다.
프로세스 확인
- 포그라운드 프로세스 : 사용자가 볼 수 있는 공간에서 실행되는 프로세스
- 백그라운드 프로세스 : 사용자가 볼 수 없는 공간에서 실행되는 프로세스
- 백그라운드 프로세스 중에서도 사용자와 상호작용하지 않고 정해진 일만 수행하는 프로세스를 서비스(윈도우) 또는 데몬(유닉스)이라 부른다.
프로세스 제어 블록
- CPU는 한번에 하나의 일만 할 수 있기 때문에, 프로세스는 차례대로 돌아가며 한정된 시간만큼만 CPU를 이용한다. → 타이머 인터럽트 발생 시 CPU 사용 종료
- 프로세스의 실행 순서를 관리하고, 자원을 배분하기 위해 운영체제는 프로세스 제어 블록(PCB)를 이용한다.
- 프로세스와 관련된 정보를 저장하는 자료 구조로 메모리의 커널 영역에 생성된다.
- 각 프로세스를 식별하기 위한 일종의 태그 데이터를 저장한다.
- 프로그램이 프로세스가 될 때 생성되며, 프로그램을 종료할 때 폐기된다.
프로세스에 담기는 정보
- 프로세스 ID (PID)
- 프로세스를 식별하기 위해 부여하는 고유한 번호
- 같은 프로그램이라도 두번 실행되면 서로 다른 PID를 갖는다.
- 레지스터 값
- 프로그램에 사용하던 레지스터 값들을 모두 저장해두었다가, 다시 CPU를 이용할 때 복원한다.
- 프로세스 상태
- CPU 스케줄링 정보
- 언제, 어떤 순서로 CPU를 할당받을지에 대한 정보
- 메모리 관리 정보
- 프로세스가 메모리의 어느 주소에 저장되어 있는지 알수 있는 정보
- 사용한 파일과 입출력장치 목록
- 프로세스 실행과정에서 사용하였던 파일과 입출력 장치 기록
문맥 교환
- CPU에서 실행되는 프로세스가 교체될 때, 다음에 이어서 실행하기 위해 기존 프로세스가 사용하던 정보를 백업해야한다.
- 이렇게 프로세스 수행을 재개하기 위해 기억해야할 정보를 문맥이라고 한다.
- PCB에 기록되는 정보들이 문맥이라 할 수 있다.
- 타이머 인터럽트가 발생하거나, 예기치 못한 상황으로 인터럽트가 발생했을 때 운영체제는 PCB에 해당 프로세스의 문맥을 백업하고, 실행할 문맥을 PCB에서 가져온다.
- 이렇게 CPU의 기존 문맥을 백업하고, 실행할 문맥을 가져와 교체하는 과정을 문맥 교환이라고 한다.
- 문맥 교환은 각 프로세스가 교체될 때마다 이루어진다.
- 문맥 교환이 너무 잦으면 오버헤드가 발생할 수 있다.
- 오버헤드 : 특정 기능을 실행하는데 걸리는 간접적인 시간, 메모리 등의 자원
어떤 기능을 수행하는데 원래 2초가 걸리지만, 만약 3초가 걸렸다면 1초의 오버헤드가 발생한 것. (간접적인 원인으로 1초가 더 걸림)
프로세스의 메모리 영역
- 프로세스가 생성될 때 커널 영역에는 PCB가 저장되고, 사용자 영역에는 4가지 영역으로 나뉘어 프로세스가 저장된다.
- 코드 영역, 데이터 영역, 힙 영역, 스택 영역
코드 영역 (텍스트 영역)
- 실행할 수 있는 기계어 명령어가 저장되는 영역
- 읽기 전용 영역(read-only)이다.
데이터 영역
- 프로그램이 실행되는 동안 유지해야하는 데이터가 저장되는 영역
코드 영역, 데이터 영역은 프로세스 실행 내내 그 크기가 변하지 않는다. 이로인해 정적 할당 영역이라고 한다.
나머지 힙 영역, 스택 영역은 프로세스 실행 중 크기가 변하여 동적 할당 영역이라 한다.
힙 영역
- 프로그래머가 직접 할당할 수 있는 저장 영역
- 할당 받은 저장공간은 반드시 반환해야하며, 그렇지 않을 경우 메모리 누수(memory leak)가 발생한다.
스택 영역
- 데이터를 일시적으로 저장되는 공간으로, 프로그램 실행 중 필요에 따라 잠깐 사용하고 제거할 데이터가 저장되는 영역
- 매개 변수, 지역 변수 등
힙 영역은 메모리의 낮은 주소에서 높은 주소로, 스택 영역은 높은 주소에서 낮은 주소로 할당되어, 할당되는 주소가 겹치지 않게한다.
정확히는 충돌이 발생하는 순간을 가능한 늦춘다. (메모리가 꽉 차는 순간이 힙 데이터와 스택 데이터가 만나는 순간이므로)
10-2 프로세스 상태와 계층 구조
- 프로세스는 저마다의 상태가 있고, 이는 PCB에 기록된다.
프로세스 상태
생성 상태(new)
- 프로세스가 생성 중인 상태로, 프로그램이 메모리와 PCB에 적재된 후, 첫 CPU 할당을 받을 때 까지의 상태
준비 상태(ready)
실행 상태(running)
- CPU를 할당 받아 실행 중인 상태
- 준비 상태에서 실행 상태로 전환되는 것을 디스패치(dispatch)라고 한다.
대기 상태(blocked)
- 프로세스 실행 도중 입출력장치 인터럽트 등 특정 이벤트 발생하여, 입출력 완료 인터럽트를 받을 때까지 대기하고 있는 상태를 말한다.
- 대기 상태가 끝나면 다시 CPU 할당을 위한 준비 상태가 된다.
종료 상태(terminated)
프로세스 상태 다이어 그램
프로세스 계층 구조
- 프로세스는 다른 프로세스를 생성할 수 있다. 이 때 생성한 프로세스를 부모 프로세스, 생성된 프로세스를 자식 프로세스라고 한다. 자식 프로세스 역시 다른 프로세스의 부모가 될 수 있다.
- 일부 운영체제에서는 PCB에 부모 프로세스의 정보인 PPID를 기록하기도 한다.
- 이렇게 부모 프로세스와 자식 프로세스로 구성된 계층 구조를 프로세스 계층 구조라고 한다.
- 모든 계층 구조에서 최상단에 있는 루트 프로세스를 최초의 프로세스라고 한다.
- 항상 1번 PID를 갖는다.
- 운영체제마다 다른 이름을 사용한다 (유닉스 : init, mac : launchd 등)
프로세스 생성 기법
- fork와 exec라는 시스템 호출을 사용하여 자식 프로세스를 생성한다.
- 부모 프로세스는 fork 시스템 호출을 사용하여 자신의 복사본을 자식 프로세스로 생성한다.
- 생성된 자식 프로세스는 exec 시스템 호출을 통해 현재 자신의 메모리 공간을 새로운 프로그램으로 덮어쓴다.
- 코드 영역과 데이터 영역의 내용이 실행할 프로그램으로 바뀌고, 나머지 영역은 초기화된다. (원래는 부모 프로세스가 갖고 있던 것)
- 부모 프로세스, 자식 프로세스 누구도 exec를 호출하지 않으면, 같은 코드를 병행하여 실행하는 프로세스가 된다.
10-3 스레드
프로세스와 스레드
- 단일 스레드 프로세스 : 프로세스에서 한번에 하나의 부분만 실행됨
- 멀티스레드 프로세스 : 프로세스 내에서 한번에 여러 부분이 실행됨 → 여러 명령어를 동시에 실행
- 프로세스 내에서 각기 다른 스레드 ID, 프로그램 카운터 값, 레지스터값 등으로 구성되기 때문에 별개의 코드를 실행할 수 있다.
- 프로세스가 보유한 자원(코드영역, 데이터영역, 힙영역, 스택영역)을 공유하면서 실행된다. 때문에 각 스레드는 실행에 필요한 최소한의 정보만 유지한 채 실행된다.
멀티프로세스와 멀티스레드
- 멀티프로세스 : 여러개의 프로세스를 동시에 실행
- 프로세스를 fork하여 사용
- 프로세스마다 각자 메모리를 차지하기 때문에 공간의 낭비가 될 수 있다.
- 멀티스레드 : 스레드를 통해 하나의 프로세스를 동시에 여러번 실행
- 메모리에 실제 존재하는 것은 프로세스 하나
- PCB에서 코드, 데이터, 힙 영역을 공유하고, 레지스터, 스택, 프로그램 카운터는 스레드별로 나누어 사용한다.
- 메모리 측면에서는 프로세스보다 효율적이고, 상호간의 통신이 쉽다는 장점이 있다.
- 스레드 하나에 문제가 생길경우 다른 스레드까지 영향을 받을 수 있다는 위험이 있다.
프로세스 간 통신 (IPC)
- 프로세스끼리도 자원을 공유하고, 데이터를 주고 받을 수 있다. 서로다른 프로세스, 스레드끼리 통신이 가능하다.
- 프로세스끼리 메모리를 공유하여 사용할 수도 있는데, 이 영역을 공유 메모리라고 한다.
- 공유메모리에 있는 변수 등을 양쪽 프로세스 모두에서 사용할 수 있다.
- 이외에도 프로세스끼리 소켓, 파이프등을 통해 통신할 수 있다.