Program

-
Static Program : 프로그램은 윈도우의 *exe 파일과 같이 컴퓨터에서 실행할 수 있는 파일을 통칭.
단, 아직 파일을 실행하지 않은 상태이기 때문에 Static Program 을 줄여 Program 이라 부른다.
-
프로그램은 코드를 작성하여 완성한다. 즉, 프로그램은 쉽게 말해 코드 덩어리 이다.
Process

-
모든 프로그램은 OS 가 메모리 공간을 할당해 줘야 실행할 수 있다.
그래서 프로그램 실행 시 파일은 메모리에 올라가게 되고,
OS 로 부터 시스템 자원(CPU) 를 할당받아 프로그램 코드를 실행시켜 우리가 사용할 수 있게 된다.
-
프로세스는 이렇게 메모리에 적재되어 CPU 에 의해 실행되는 컴퓨터 프로그램을 지칭한다.
즉, 컴퓨터에서 작업중인 프로그램이 프로세스 이다.
좀 더 정확하게 말하면 운영체제로부터 자원을 할당받은 작업의 단위 이다.


-
각 프로세스는 고유한 프로세스 ID(PID) 를 가지며,
OS 는 프로세스 간의 자원 공유를 관리한다.
-
하지만 막상 작업관리자에서 확인하면 창을 하나 켰을 뿐인데 Chrome의 프로세스는 여러개가 존재한다.
-
이러한 프로세스들을 멀티 프로세스 라고 하며 부모 프로세스 와 여러 자식 프로세스로 이루어져 있다.
멀티 프로세스와 멀티 태스킹 관련은 다음 시리즈에서 다뤄보려고 한다.
프로세스의 자원 구조


- 프로세스는 Stack / Heap / Data / Text(code) 4가지 영역으로 나눌 수 있다.
- 프로그램이 여러 개 실행 된다면 메모리에 프로세스들이 담길 주소 공간이 생성된다.
- 그리고 그 공간 안에 Stack / Heap / Data / Text(code) 공간이 만들어 진다.
Stack 영역
- 프로그램이 자동으로 사용하는 메모리 영역
- 함수 호출과 관계되는 지역변수, 매개변수가 저장
- 함수 호출시 생성되어 끝나면 반환된다.
- Stack 영역은 메모리의 높은 주소에서 낮은 주소 방향으로 할당된다.
- Code / Data 영역은 정적영역이지만 Stack / Heap 영역은 크기가 변하는 동적 영역이다.
Heap 영역
- 생성자, 인스턴스와 같은 동적으로 할당되는 데이터를 위해 존재하는 공간.
- 사용자에 의해 메모리 공간이 동적으로 할당되고 해제 된다.
- Heap 영역은 메모리의 낮은 주소에서 높은 주소 방향으로 할당 된다.
- 사실상 Stack 과 같은 영역을 공유하고 있다.
Data 영역
- 프로그램의 전역변수와 정적(static) 변수, 배열, 구조체(structure) 가 저장되는 영역
- 초기화된 데이터는 data 영역에 저장
- 초기화되지 않은 데이터는 BSS(block Stated Symbol) 영역에 저장
- 상수 키워드 선언된 변수나 문자열 상수는 rodata(Read only data) 영역에 저장
- 프로그램의 시작과 함께 할당되며 프로그램이 종료되면 소멸한다.
Text / Code 영역
- 우리가 작성한 코드가 컴파일 된 후 기계어로 번역되어 저장되어 있는 곳
- 오직 읽기 전용이다.
- 프로그램이 끝날 때까지 메모리에 남아 있다.
Java 프로세스는 JVM이라는 가상 시스템에서 실행된다. ( JVM 메모리 구조 )
이와 같은 구조는 컴파일된 Java 클래스 파일(bytecode)를 다양한 OS 환경에서 실행 가능하게 해준다.
-> 프로세스 자원 구조와 JVM 메모리 구조의 차이?
프로세스의 자원 공유
- 기본적으로 각 프로세스는 메모리에 별도의 주소 공간에서 실행되기 때문에 다른 프로세스의 변수나 자료구조에 접근할 수 없다.
- 그러나 현재 우리가 사용하는 프로그램을 보면 다른 프로그램에 있는 정보를 가져올 수 있는 경우가 많다.
- 이처럼 특별한 방법을 통해 프로세스가 다른 프로세스의 정보에 접근하는 것이 가능하다.
- IPC ( Inter-Process Communication )
- LPC ( Local inter-Process Communication )
- 별도로 공유 메모리를 만들어서 정보를 주고 받도록 설정
- 하지만 프로세스 자원 공유는 단순히 CPU 레지스터 교체 뿐만 아니라 RAM,CPU 사이의 캐시 메모리까지 초기화되기 때문에 자원 부담이 큰 단점이 있다.
- IPC 의 경우 자체로 오버헤드가 발생한다.
파이프나 소켓 같은 IPC 기법은 데이터를 복사하거나 버퍼링을 하는 과정에서 성능 저하가 발생할 수 있기 때문이다. 또한 코드의 복잡도를 증가시킨다.
- 그래서 다중 작업이 필요한 경우엔 스레드를 이용하는 것이 훨씬 효율적이다.
프로세스 & 스레드 동시 실행 원리
- 음악을 듣고, 웹서핑을 하고, 메신저의 메세지를 확인할 수 있는 이유는 멀티 태스킹 기술 덕분이다.
- 멀티 태스킹이란 컴퓨터에서 여러 작업을 동시에 실행하는 능력을 말한다.
- 좀더 자세히 말하자면, OS 를 통해 CPU 가 작업하는데 필요한 자원을 프로세스 or 스레드 간에 나누는 행위를 말한다 ( 프로세스와 스레드를 동시에 처리 )
멀티코어 & 스레드

- CPU 한 대는 여러 개의 코어를 가질 수 있다. ( 4코어, 8코어, 12코어 ... )
- 즉, 명령어를 메모리에서 뽑아 해석하고 실행하는 반도체 유닛이 코어 갯수만큼 있는 것이다.
- 코어는 물리적 코어 갯수이고 스레드는 논리적 코어 갯수를 말한다.
( 4코어 8 스레드는 물리적 코어 하나가 스레드 두 개 이상 동시에 실행 가능하다는 의미로, 운영체제가 8개의 작업을 동시에 처리할 수 있다는 뜻이다. )
여기서 다루는 스레드는 프로그램의 스레드가 아닌 CPU 의 하드웨어적 스레드를 말한다.
8 스레드 : 8 개의 논리적 코어 갯수. 즉, 8개 프로세스 가능
- 그런데 우리는 컴퓨터 이용 시 프로그램을 수십, 수백개 켜 놓고 이용한다. 이를 8 개의 논리적인 스레드로 어떻게 처리하는 것일까
병렬성과 동시성

- 병렬성 ( Parallelism )
: 여러개의 코어에 맞춰 여러개의 프로세스, 스레드를 돌려 병렬로 작업을 동시 수행하는 것
물리적으로 정말로 동시에 실행한다.
듀얼코어, 쿼드코어, 옥타코어 등 멀티코어 프로세서가 달린 컴퓨터에서 할 수 있는 방식

- 동시성 ( Concurrency )
: 둘 이상의 작업이 동시에 실행하는 것처럼 보이게 하는 것.
1 개의 코어가 있고 4 개의 프로세스들이 있다고 가정하면, 계속 번갈아가면서 아주 잘게 나누어 아주 조금씩만 처리함으로서 마치 동시에 실행되는 것처럼 보이게 하는 것이다.
이때 프로세스들을 매우 빠르게 번갈아가며 처리하기 때문에 마치 동시에 돌아가는 것처럼 보인다.
이렇게 번갈아가 바꾸는 것을 Context Switching 이라고 부른다.
동시성 필요 이유
- 병렬성은 정말로 각 코어에 프로세스를 나눠 실행하는 것이므로 최종 작업 시간이 절반으로 줄어든다.
- 하지만 동시성은 동시에 돌아가는 것 처럼 보이는 것이라 최종 작업 시간은 차이가 별로 없다.
- 그래도 동시성이 필요한 이유는 하드웨어적 한계와 논리적인 효율 때문이다
하드웨어적 한계
- CPU 발열 때문에 깡 클럭으로 성능을 올리기에는 한계가 있어 코어의 성능 보다 코어를 여러 개 탑재한 CPU 들이 출시하고 있다.
- 하지만 아무리 코어를 많이 넣어도 수십개는 어려우니 결국 하드웨어적 제한이 걸린다.
- 수십 수백개의 프로세스를 돌리기 위해선 결국 동시성이 필요하다.
논리적인 효율
- 4코어 8스레드 CPU 환경에서 16 개의 프로세스가 있고, 그 중 반은 오래걸리는 작업이고 나머지는 짧은 시간을 필요로 하는 작업이라 가정하자.
- 논리적인 8개의 코어 ( 8 스레드 ) 이기 때문에 최대 8 개까지 동시에 실행할 수 있는데, 만일 8 개가 오래 걸리는 작업이 동시에 처리되기 시작했다고 치자.
- 그러면 나머지 가벼운 작업들마저 오래 걸리는 것이 끝날 때까지 기달려야 한다.
- 이런 비효율적인 면을 극복하기 위해서 작업을 잘게 나눠 번갈아 처리하는 동시성이 필요하다.
멀티 프로세스는 하나의 응용 프로그램에 대해 동시에 여러 개의 프로세스를 실행할 수 있게 하는 기술을 말하고
여기서는 각각의 프로세스들이 한 코어에서 각 프로세스들을 나눠 잘게 쪼개서 사용하는 동시성을 얘기한다.
프로세스 스케쥴링 (Process Scheduling)
-
프로세스는 생명 주기를 가지고 있다.
-
OS 는 이러한 생명 주기를 관리하고 조정하여 시스템 자원을 효율적으로 사용할 수 있게 한다.
-
OS에서 CPU 를 사용할 수 있는 프로세스를 선택하고 CPU 를 할당하는 작업을 프로세스 스케쥴링이라고 한다.
-
프로세스의 우선순위, 작업량 등을 고려하여 효율적으로 배치하여 시스템 성능을 향상시킨다.
-
그래서 스케쥴링은 멀티 태스킹 작업을 만들어 내는 데에 있어서 핵심적인 부분이다.
-
스케쥴링은 다양한 알고리즘 방식으로 동작한다.
FCFS(First-Come, First-Served),
SJF(Shortest-Job-First),
Priority, RR(Round-Robin), Multilevel Queue 등...
참고 : https://woo-dev.tistory.com/148
프로세스 상태와 전이

- NEW (생성) : 프로세스 생성되고 준비는 X
- READY (준비) : 실행대기 상태. CPU 를 할당받을 수 있는 상태.
- RUNNING (실행) : CPU 할당 받아 프로세스 실행
- WAITING (대기) : 특정 이벤트( 입출력 요청 등 ) 발생하여 대기상태 ( CPU 할당 X )
- TERMINATED (종료) : 프로세스 실행 완료하고 종료된 상태 ( 더이상 실행 X, 메모리에서 제거 )

-
프로세스 상태 전이는 프로세스가 실행되는 동안 상태가 OS 에 의해 변경되는 것이다.
-
OS 는 프로세스의 상태를 감시하고, 상태를 기반으로 프로세스 스케쥴링을 통해 프로세스를 관리하고 제어한다.
- Admitted : new -> ready ( 프로세스 생성 승인 받음 )
- Dispatch : ready -> running ( 준비 상태 프로세스 중 하나가 스케쥴러에 의해 실행 )
- Interrupt : running -> ready ( 예기치 않은 이벤트 발생으로 현재 실행 중인 프로세스를 준비 상태로 전환하고 해당 작업을 먼저 처리 )
- I/O or event wait : running -> waiting ( 실행 중인 프로세스가 입출력이나 이벤트 처리를 해야 하는 경우 끝날 때까지 대기상태로 전환 )
- I/O or event completion : waiting -> ready ( 입출력, 이벤트 처리 끝낸 프로세스를 다시 준비 상태로 만듦 )
Process Context Switching
- CPU 가 한 프로세스에서 다른 프로세스로 전환할 때 발생하는 일련의 과정
- CPU 는 한 번에 하나의 프로세스만 실행할 수 있으므로 동시성을 사용할 경우 Context Switching 이 필요하다.
Context Switching
1. 동작 중인 프로세스가 대기하면서 해당 프로세스의 상태(Context) 를 보관
2. 다음 순서의 프로세스가 동작하면서 보관한 프로세스의 상태를 복구하는 작업을 말한다.
컨텍스트 스위칭이 일어날 때 다음번 프로세스는 스케쥴러가 결정한다.

PCB ( Process Control Block )
-
프로세스를 Context Switching 할 때, 기존 프로세스의 상태를 보관해야 다음에 이어서 할 수 있고 또 새로 해야 할 작업의 상태 또한 알 수 있다.
-
이때 PCB 에 저장이 가능하다.
즉, 프로세스 스케줄링을 위해 프로세스에 관한 모든 정보를 저장하는 임시 저장소이자 자료구조다.
-
PCB 는 프로세스가 생성과 동시에 OS 에 의해 생성이 된다.
그리고 프로세스가 종료되면 같이 종료가 된다.
-
OS 는 PCB 에 담긴 프로세스 고유 정보를 통해 프로세스를 관리하고 스케쥴링을 수행한다.

- Pointer ( 포인터 ) : 프로세스 현재 위치 저장하는 포인터 정보
- Process state ( 프로세스 상태 ) : New / Ready / Running / Running / Waiting / Terminated 저장
- Process ID ( PID ) : 고유 ID
- Program counter ( 프로그램 카운터 ) : 프로세스를 위해 실행될 다음 명령어의 주소를 포함하는 카운터를 저장
- Register ( 레지스터 ) : 누산기, 베이스, 레지스터 및 범용 레지스터를 포함하는 CPU 레지스터에 있는 정보
- Memory Limits ( 메모리 제한 ) : OS 에서 사용하는 메모리 관리 시스템에 대한 정보
- List of open file ( 열린 파일 목록 ) : 프로세스를 위해 열린 파일 목록
Context Switching 과정

- CPU 가 Process P1 실행
- 일정 시간 Interrupt or system call 발생
- Process P1 의 상태를 PCB1 에 저장
- 다음 실행할 Process P2 선택하고 Process P2 상태를 PCB2 에서 불러옴
- CPU 가 Process P2 실행
- 일정 시간 Interrupt or system call 발생
- Process P2 의 상태를 PCB2 에 저장
- 다음 실행할 Process P1 선택하고 Process P1 상태를 PCB1 에서 불러옴
- CPU 가 Process p1 이어서 실행
이때 CPU 는
1 - Executing ( 실행 ) / 2~4 - idle ( 대기 ) / 5 - Executing ( 실행 ) / 6~8 - idle ( 대기 ) / 9 - Executing ( 실행 )
상태로 변한다.
Context Switching Overhead
- 컨텍스트 스위칭 과정은 빠른 반응성과 동시성을 제공하지만
변경 과정에서 PCB에 저장되고 불러오는 등의 작업이 수행되어 시스템에 많은 부담을 주게 된다.
- 위 과정 그림을 보면 P1 <-> P2 로 서로 이동할 때 대기 (idle) 상태에 조금 있다가 실행 (Executing) 하는 것을 알 수 있다.
- 이 대기 상태의 간극이 바로 Overhead 이다.
- 교체 과정에서 과하게 오버헤드가 발생하면 오히려 싱글스레드보다 성능이 떨어지는 현상이 나타날 수 있다.
오버헤드는 다음과 같은 행위에 의해서 발생한다.
- PCB 를 저장하고 복원하는데 비용이 발생한다.
- 프로세스 교체에 CPU 캐시 메모리에 저장된 데이터가 무효화 된다.
- 이 과정에서 메모리 접근 시간이 늘어나고 성능 저하가 발생할 수 있다.
- CPU 스케쥴링 알고리즘에 따라 프로세스를 선택하는 비용도 만만치 않다.
출저 : https://inpa.tistory.com/entry/%F0%9F%91%A9%E2%80%8D%F0%9F%92%BB-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4-%E2%9A%94%EF%B8%8F-%EC%93%B0%EB%A0%88%EB%93%9C-%EC%B0%A8%EC%9D%B4#%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4%EC%9D%98_%EC%9E%90%EC%9B%90_%EA%B5%AC%EC%A1%B0