프로그램이란? 어떤 작업을 위해 실행할 수 있는 파일의 의미.
프로세스(Process)
프로세스는 일반적으로 프로세서(처리기, CPU)에 의해 처리되는 사용자 프로그램, 시스템 프로그램, 즉 실행중인 프로그램을 의미하며, 작업(Job),태스크(Task)라고도 한다.
-
실행 중인 프로그램으로 디스크로부터 메모리에 적재되어 CPU의 할당을 받은 작업의 단위다.
-
운영체제로부터 시스템 자원을 할당받는다.
-
할당받는 시스템 자원
- CPU 시간
- 운영되기 위한 주소 공간
- Code, Data, Stack, Heap의 구조로 되어있는 독립된 메모리 영역
-
Code: 코드 자체를 구성하는 메모리 영역(프로그램 명령)
-
Data: 전역 변수, 정적 변수, 배열 등 (초기화된 데이터)
-
Stack : 지역변수, 매개변수, 리턴 값(임시 메모리 영역)
-
Heap : 동적 할당 시 사용(new(), mallock() 등)
-
단순하게 말하면 일을 처리하는 일련의 과정이다
ex) 아침에 일어나 학교에 가는 과정도 하나의 프로세스라고 할 수 있다.
-
아침에 일어나서 씻고 준비를 한다.
-
역으로 걸어간다.
-
지하철을 탄다.
-
역에서 내려 학교로 간다.
-
기본적으로 프로세스마다 최소 1개의 스레드를 갖는다. (메인 스레드)
-
프로세스는 각각 별도의 메모리 영역(주소 공간)을 할당받는다. [ Code,Data,Stack,Heap]
-
한 프로세스는 다른 프로세스의 변수나 자료구조에 접근할 수 없으며, 접근을 위해서는 IPC 통신이 필요하다.
-ex) 파이프, 파일, 소켓, 등을 이용한 통신 방법 이용
프로세스 제어 블록(Process Control Block, PCB)
- 특정 프로세스에 대한 중요한 정보를 저장하고 있는 커널 내의 자료구조이다.
- OS는 프로세스를 관리하기 위해 프로세스의 생성과 동시에 고유한 PCB를 생성한다.
- 프로세스는 CPU를 할당받아 작업을 처리하다가 프로세스 전환이 발생하면 진행하던 작업을 저장하고 CPU를 반환해야 한다. 이때 작업의 진행 상황을 모두 PCB에 저장한다. 그리고 다시 CPU를 할당받게 되면 PCB에 저장되었던 내용을 불러와 종료되었던 시점부터 다시 작업을 수행한다.
- PCB에 저장되는 정보
-프로세스 식별자(Process ID, PID) : 프로세스 식별 번호
-프로세스 상태: new, ready, running, waiting, terminated 등의 상태를 저장
-프로그램 카운터(Program Counter, PC): 프로세스가 다음에 실행할 명령어의 주소를 가리킨다.
-CPU 레지스터
-CPU 스케줄링 정보: 프로세스의 우선순위, 스케줄 큐에 대한 포인터 등
-메모리 관리 정보: 페이지 테이블 또는 세그먼트 테이블 등과 같은 정보를 포함한다.
-입출력 상태 정보: 프로세스에 할당된 입출력 장치들과 열린 파일 목록
-어카운팅 정보: 사용된 CPU 시간, 시간 제한, 계정 번호 등
스레드(Thread)
- 프로세스의 실행 단위라고 할 수 있으며, 한 프로세스 내에 동작되는 여러 실행 흐름으로 프로세스 내의 주소 공간이나 자원을 공유할 수 있다.
- 스레드는 프로세스 내의 Code, Data, Heap 영역은 다른 스레드와 공유하고, Stack 영역을 따로 할당받는다.
- 여러 스레드는 한 프로세스 내의 Code, Data, Heap 영역을 공유하지만, 프로세스 간에는 메모리에 접근할 수 없다.
- 스레드는 별도의 레지스터와 스택을 갖고 있으며, 다른 영역을 공유한다. 따라서 한 스레드가 프로세스의 자원을 변경하면, 다른 스레드도 그 변경 결과를 즉시 확인할 수 있다.
요약
프로세스 : 자신만의 고유 공간과 자원을 할당받아 사용하는 작업의 단위.
스레드 : 프로세스 내에서 실행되는 흐름의 단위로, 다른 스레드와 프로세스의 자원과 공간을 공유하면서 사용.
멀티 프로세스 vs 멀티 스레드
멀티 프로세스(Multi Process)
- 하나의 응용프로그램을 여러 개의 프로세스로 구성하여 각 프로세스가 하나의 작업을 처리하도록 하는 것.
- 장점
1) 여러 개의 자식 프로세스 중 하나에 문제가 발생하면 그 자식 프로세스만 주는 것 이상으로 다른 영향이 확산되지 않는다. (안정성)
- 단점
1) Context Switching에서의 오버헤드
-프로세스는 각 독립된 메모리 영역을 할당받았기 때문에 공유하는 메모리가 없다. 따라서 캐시 메모리 초기화 등의 무거운 작업이 진행되고 많은 시간이 소모되는 등의 오버헤드가 발생할 문제가 있다.
2) 프로세스 간 통신 기법 IPC
-프로세스는 각 독립된 메모리 영역을 할당받았기 때문에 프로세스들 사이에서 변수나 자료구조를 공유할 수 없다. 따라서 IPC라는 방법을 사용해야 하며, 이는 어렵고 복잡한 통신 방법이다.
멀티 스레드(Multi Thread)
- 하나의 응용 프로그램을 여러 개의 스레드로 구성하고 각 스레드가 하나의 작업을 처리하도록 하는 것.
- 윈도우, 리눅스 등 많은 OS들이 멀티 프로세싱을 지원하고 있지만, 멀티 스레딩을 기본으로 하고 있다.
- 웹 서버는 대표적인 멀티 스레드 응용 프로그램이다.
- 장점
-메모리 공간과 시스템 자원 소모가 줄어들게 된다.
-스레드 간 통신시, 전역 변수의 공간인 Data와 또는 동적으로 할당된 공간인 Heap 영역을 이용해 데이터를 주고 받으므로 통신 방법이 간단하다.
-Context switching 시, 캐시 메모리를 비울 필요가 없기 때문에 비용이 적고 더 빠르다.
-따라서 시스템의 처리량이 향상되고 자원 소모가 줄어들며, 자연스럽게 프로그램의 응답 시간이 단축됨.
- 단점
-서로 다른 스레드가 Data,Heap 영역 등을 공유하기 때문에 어떤 스레드가 다른 스레드에서 사용중인 변수나 자료구조에 접근하여 엉뚱한 값을 읽어오거나 수정할 수 있다. 즉, 자원 공유의 문제가 발생함. (동기화)
-하나의 스레드에 문제가 생기면 전체 프로세스가 영향을 받는다.
-주의 깊은 설계가 필요하며, 디버깅이 까다롭다.
멀티 스레드 vs 멀티 프로세스
멀티 스레드는 멀티 프로세스보다 적은 메모리 공간을 차지하고 Context Switching이 빠르다는 장점이 있지만, 오류로 인해 하나의 스레드가 종료되면 전체 스레드가 종료될 수 있다는 점과 동기화 문제를 가지고 있다.
반면, 멀티 프로세싱 방식은 하나의 프로세스가 죽더라도 다른 프로세스에는 영향을 끼치지 않고 정상적으로 수행된다는 장점이 있지만, 멀티 스레드보다 많은 메모리 공간과 CPU 시간을 차지한다는 단점이 존재한다.
이 두 가지는 동시에 여러 작업을 수행한다는 점에서 같지만 적용해야 하는 시스템에 따라 적합/부적합이 구분된다. 따라서 대상 시스템의 특징에 따라 적합한 동작 방식을 선택하고 적용해야 한다.
Q. 스택을 스레드마다 독립적으로 할당하는 이유는 뭘까?
스택은 함수 호출시 전달되는 인자, 복귀 주소값 및 함수 내에서 선언하는 변수 등을 저장하기 위해 사용되는 메모리 공간.
스택 메모리 공간이 독립적이라는 것은 독립적인 함수 호출이 가능함을 의미하고 이는 독립적인 실행 흐름이 추가된다는 것이다. 따라서 스레드의 정의에 따라 독립적인 실행 흐름을 추가하기 위한 최소 조건으로 독립된 스택을 할당하는 것이다.
Q. PC 레지스터를 스레드마다 독립적으로 할당하는 이유는 뭘까?
PC값은 스레드가 명령어의 어디까지 수행했는지를 나타내게 된다. 스레드는 CPU를 할당받았다가 스케줄러에 의해 다시 선점당한다. 그렇기 때문에 명령어가 연속적으로 수행되지 못하고 어느 부분까지 수행했는지 기억할 필요가 있다. 따라서 PC 레지스터를 독립적으로 할당한다.
Q. 멀티 프로세스 대신 멀티 스레드를 사용하는 이유는?
- 프로그램을 여러개 키는 것보다 하나의 프로그램 안에서 여러 작업을 해결하는 것이 더욱 효율적이기 때문이다.
- 프로세스를 생성하여 자원을 할당하는 시스템 콜이 줄어들어 자원을 효율적으로 관리할 수 있다.
- Context Switching시, 캐시 메모리를 비울 필요가 없기 때문에 비용이 적고 더 빠르다. -> 스레드는 Stack 영역만 초기화하면 되기 때문.
- 스레드는 프로세스 내의 메모리를 공유하기 때문에 데이터 전달이 간단하므로 IPC에 비해 비용이 적고 더 빠르다. -> 스레드는 프로세스의 Stack 영역을 제외한 모든 메모리를 공유하기 때문.
Context Switching이란?
- CPU는 한번에 하나의 프로세스만 처리할 수 있다.
- 여러 프로세스를 처리해야하는 상황에서 현재 진행중인 Task(프로세스, 스레드)의 상태를 PCB에 저장하고 다음에 진행할 Task의 상태값을 읽어 적용하는 과정을 말한다. ( 다른프로세스에게 CPU를 할당해 작업을 수행하는 과정을 말한다.)
- 과정
-Task의 대부분 정보는 Register에 저장되고 PCB로 관리된다.
-현재 실행하고 있는 Task의 PCB 정보를 저장한다.
-다음 실행할 Task의 PCB 정보를 읽어 Register에 적재하고 CPU가 이전에 진행했던 과정을 연속적으로 수행할 수 있다.
- Context Switching은 많은 비용이 소모된다.
-Cache 초기화
-Memory mapping 초기화
-커널은 항상 실행되어야 한다.
- Context Switching의 비용은 프로세스가 스레드보다 더 많이 든다.
- 이유: 스레드는 Stack영역을 제외한 모든 메모리를 공유하기 때문에 Context Switching 발생시 Stack 영역만 변경을 진행하면 되기 때문이다.
Tread-safe
- 멀티스레드 환경에서 여러 스레드가 동시에 하나의 객체 및 변수(공유 자원)에 접근할 때, 의도한 대로 동작하는 것을 말한다.
- 이러한 상황을 "Thread-safe 하다"라고 표현한다.
- Thread-safe 하게 구현하기
-이를 위해서는 공유 자원에 접근하는 임계영역(critical section)을 동기화 기법으로 제어해줘야 한다. 이를 '상호배제'라고 한다.
-동기화 기법으로는 뮤텍스나 세마포어가 존재한다.
- Reentrant
-재진입성이라는 의미로, 어떤 함수가 Reentrant하다는 것은 여러 스레드가 동시에 접근해도 언제나 같은 실행 결과를 보장한다는 의미이다.
-이를 만족하기 위해서 해당 서브루틴에서는 공유자원을 사용하지 않으면 된다.
ex) 정적(전역) 변수를 사용하거나 반환하면 안되고 호출 시 제공된 매개변수만으로 동작해야 한다.
-따라서, Reentrant하다면 Thread-safe하지만 그 역은 성립하지 않는다.