Search
🧸

프로세스와 스레드

생성일
2023/08/06 04:44
태그
혼공컴구
운영체제
날짜
3 more properties

학습 목표

프로세스 제어 블록이란
문맥 교환의 정의와 과정
프로세스는 메모리에 어떻게 배치되는지
프로세스 상태와 프로세스 계층 구조
스레드의 개념을 이해하고, 멀티프로세스와 멀티스레드

프로세스 개요

프로세스 = 실행 중인 프로그램
실행 전의 프로그램 = 보조기억장치 속의 데이터 덩어리
실행 중인 프로그램 = 메모리에 적재 된 프로그램 = 프로세스
포그라운드 프로세스, foreground process
사용자가 보는 앞에서 실행되는 프로세스
백그라운드 프로세스, background process
유닉스 체계 ⇒ 데몬, daemon
윈도우 체계 ⇒ 서비스, service

프로세스 제어 블록

모든 프로세스는 실행되기 위해 CPU가 필요
CPU 자원은 한정되어 있음
프로세스는 돌아가며 한정된 시간 동안만 CPU를 이용
정해진 시간이 끝나면 끝났다고 알림 (타이머 인터럽트)
타이머 인터럽트를 날리고 다음 차례가 올 때까지 기다린다
해당 과정을 위해 운영체제는 PCB를 이용한다
PCB, Process Control Block, 프로세스 제어 블록
프로세스와 관련된 정보를 저장하는 자료구조
상품 태그처럼, 프로세스를 식별하기 위한 정보 포함
PCB는 커널 영역에서 생성된다
사용자 영역에서 생성될 수 없다
PCB는 프로세스 생성 시에 만들어지고, 실행이 끝나면 폐기된다
프로세스 자체와 생명주기를 같이 한다

PCB에 담긴 정보

프로세스 ID

PID, Process ID
프로세스를 식별하기 위해 부여하는 고유한 번호
같은 프로그램이라도 실행될 때마다 서로 다른 값 부여된다

레지스터 값

자신의 차례가 돌아오면 사용했던 레지스터의 중간값들을 모두 복원
그래야 하던 일을 이어서 진행할 수 있다
Program Counter를 포함하는 레지스터 값들 …

프로세스 상태

현재 프로세스의 상태
입출력장치를 기다리는 상태인가?
CPU를 사용하기 위해 기다리는 상태인가?
현재 CPU를 이용하고 있는 상태인가?

CPU 스케쥴링 정보

프로세스가 언제, 어떤 순서로 CPU를 할당받을 지에 대한 정보

메모리 관리 정보

프로세스가 어느 주소에 저장되어있는가에 대한 정보
프로세스마다 메모리에 저장된 위치가 다르다
PCB에는 베이스 레지스터, 한계 레지스터 값과 같은 정보 있다
페이지 테이블 정보도 담긴다

사용한 파일과 입출력장치 목록

프로세스가 실행 과정에서 사용한 입출력장치나 파일 → PCB에 명시됨 (기록됨)
어떤 입출력장치가 이 프로세스에 할당 됐는 지
어떤 파일이 이 프로세스에 의해 열렸는지

문맥 교환

문맥(context): 프로세스가 다음 차례에 하던 일을 이어할 수 있도록 기억해야하는 정보
하나의 프로세스 문맥은 해당 프로세스의 PCB에 표현
PCB에 기록되는 정보 = 문맥 이라고 봐도 무관
인터럽트가 발생하면 운영체제는 해당 프로세스의 PCB에 문맥 업데이트

프로세스의 메모리 영역

프로세스가 생성되면 커널 영역에 PCB가 생성
사용자 영역에는 프로세스가 어떻게 배치될까?

코드 영역

Code segment, Text segment
코드 영역, 텍스트 영역
실행할 수 있는 코드 (기계어로 이루어진 명령어)가 배치
데이터가 아닌 CPU가 실행할 명령어가 담김
쓰기는 금지된 영역 (읽기 전용, Read-only)

데이터 영역

Data segment
잠깐 썼다 지우는 게 아닌, 프로그램이 실행되는 동안 유지되어야 할 데이터가 저장되는 곳
대표적으로 전역변수 (global variable)
코드 영역 + 데이터 영역
→ 크기가 변할 일이 없는 영역
⇒ 정적 할당 영역

힙 영역

Heap segment
프로그래머가 직접 할당할 수 있는 영역
다 사용하면 꼭 반환해야한다
반환 = 운영체제에 사용하지 않겠다고 알려주는 것
반환하지 않으면 메모리 누수(memory leak) 발생

스택 영역

Stack segment
데이터를 일시적으로 저장하는 공간
대표적으로 함수의 실행이 끝나면 사라질 지역 변수
힙 영역 + 스택 영역
실시간으로 크기가 변할 수 있다
⇒ 동적 할당 영역

프로세스 상태와 계층 구조

프로세스 상태

프로세스는 번갈아 가면서 실행되기 때문에 여러 상태를 거친다
운영체제는 PCB의 프로세스 상태를 인식하고 관리

생성 상태

new
프로세스를 생성중인 상태
이제 막 메모리에 적재되어 PCB를 할당받은 상태
실행할 준비가 완료되면 준비 상태로 바뀜 (바로 실행되는 게 아님)

준비 상태

ready
당장이라도 CPU를 할당받아 시작할 수 있지만, 차례를 기다리고 있는 상태
자신의 차례가 되면 CPU를 할당받아 실행 상태가 됨
디스패치(Dispatch)
준비 중의 프로세스가 실행 상태로 전환되는 것

실행 상태

running
CPU를 할당받아 실행 중인 상태
자신에게 할당된 시간을 모두 쓰면 (타이머 인터럽트가 발생하면)
다시 준비상태가 된다
혹은, 실행 도중 입출력장치를 사용하여 입출력 장치의 작업이 끝날 때까지 기다려야하면
대기 상태가 된다

대기 상태

blocked
실행 도중 입출력장치를 사용하는 경우
입출력 작업은 CPU에 비해 매우 느리다
입출력 끝날 때까지 (입출력 완료 인터럽트를 받을 때까지) 기다려야 한다
이렇게 기다리는 상태를 대기상태, blocked 라고 한다
입출력 작업이 완료되면 해당 프로세스는 다시 준비 상태가 된다
대기 상태의 일반적 정의
입출력이 유일한 이유는 아님. 특정 이벤트가 일어나길 기다릴 때 프로세스는 대기 상태가 된다. 다만, 프로세스가 대기 상태가 되는 대부분의 원인이 “입출력 작업” 이기 때문에 큰 차이는 없다

종료 상태

terminated
프로세스가 종료된 상태
프로세스가 종료되면 운영체제는 PCB와 프로세스가 사용한 메모리를 정리한다
이런 도표를 프로세스 상태 다이어그램 (Process State Diagram)이라고 한다

프로세스 계층 구조

프로세스는 실행 도중 시스템 호출을 통해 다른 프로세스를 생성할 수 있다
원래 프로세스: 부모 프로세스, parent process
생성된 프로세스: 자식 프로세스, child process
서로 다른 프로세스이기 때문에 다른 PID를 가진다
일부 운영체제는 자식 프로세스에 부모의 PID를 PPID 값으로 기록하기도 한다

프로세스 생성 기법

복제와 옷 갈이입히기
fork, exec라는 시스템 호출 이용
부모는 fork를 통해 자신의 복사본을 자식 프로세스로 생성
fork: 자신의 복사본을 만드는 시스템 호출
부모의 프로세스 자원들 (메모리 내용, 열린 파일 목록 등) 상속
다만 pid나 저장된 메모리 위치는 다르다
자식은 exec를 통해 자신의 메모리 공간을 다른 프로그램으로 교체
exec: 자신의 메모리 공간을 새로운 프로그램으로 덮어쓰는 시스템 호출
즉, 새로운 프로그램 내용으로 전환하여 실행
메모리 공간에 새로운 프로그램이 덮어 써진다는 점에서 옷 갈아입기
코드 영역과 데이터 영역은 새로 실행할 프로그램의 내용으로 교체
나머지 영역은 초기화

예시

bash에 ls 명령어를 쳤다
셸 프로세스는 fork → 자식 프로세스는 exec를 통해 ls 실행을 위한 프로세스로 전환
메모리 공간은 ls 명령어를 실행하기 위한 내용들로 채워짐

예시 2

만약 자식 부모 둘 다 exec를 호출하지 않는다면
같은 코드를 병행하여 실행하는 프로세스가 된다

스레드

스레드란 프로세스를 구성하는 실행 (흐름)의 단위이다
하나의 프로세스는 여러 개의 스레드를 가질 수 있다
스레드를 이용하면 하나의 프로세스에서 여러 부분을 동시에 실행 가능

프로세스와 스레드

하나의 프로세스가 하나의 흐름만 가지는 경우
한 번에 하나의 부분만 실행
⇒ 단일 스레드 프로세스
스레드라는 개념의 도입 → 프로세스를 구성하는 여러 명령어들을 동시에 수행 가능
스레드 = 프로세스를 구성하는 실행 단위
스레드는 프로세스 내에서 각기 다른 스레드 ID, PC, 레지스터 값, 스택으로 구성
각기 다른 레지스터 값, 스택 → 각기 다른 코드 실행 가능
스레드는 실행에 필요한 최소한의 정보(PC, 레지스터, 스택)만 유지
최대한의 프로세스 자원을 공유하며 실행 (스레드의 핵심)
리눅스의 프로세스와 스레드
리눅스는 프로세스와 스레드를 구분하지 않고 태스크(task)라는 이름으로 통일하여 명명

멀티프로세스와 멀티스레드

프로세스를 fork하여 같은 작업을 반복하면
코드, 데이터, 힙 영역을 비롯한 모든 데이터 자원이 복제되어 메모리에 적재
즉, PID와 저장된 메모리 주소를 제외한 모든 것이 동일한 프로세스 두 개가 통째로 메모리에 적재
fork 10번이면 똑같은 애 10 개가 .. ⇒ 낭비!
멀티 프로세스
멀티 스레드
코드, 데이터, 힙 영역 공유
열린 파일과 같은 프로세스 자원 공유
효율적인 메모리 사용, 서로 협력하여 통신하는 일에 유리
단점: 하나의 스레드 문제 → 다른 스레드도 영향
프로세스 간 통신, IPC, Inter-Process Communication
각각의 프로세스는 서로 공유하는 메모리 영역을 두어 데이터를 주고받을 수 있다. 프로세스들이 공유할 수 있는 메모리를 공유 메모리(shared memory)라고 한다. 이 외에도, 소켓, 파이프 등을 통해 통신할 수 있다.