단일 프로세스(Single Process)
- 초창기 컴퓨터는 단일 프로세스 시스템으로, 한 번에 하나의 프로그램만이 실행할 수 있어서, 또 다른 프로그램을 실행하고 싶다면 현재 프로그램을 종료해야 했다. 그리고 프로그램 실행 중 *I/O(입출력) 작업이 발생하면 CPU 는 프로세스를 멈추고 대기하게 되어 CPU 사용률이 비효율적으로 낮아지게 된다.
- I/O(Input/Output) : 프로그래밍에서 파일을 읽고 쓰는 것, 서버 네트워크의 어딘가와 데이터를 주고 받는 것, 마우스, 키보드와 같은 입출력 장치와 데이터를 주거나 받는 것을 의미한다.
- 위 문제를 해결하기 위해 여러개의 프로그램(멀티 프로그래밍)을 메모리에 올려놓고 하나의 CPU 에서 번갈아 가며 동시에 실행시키는 방안을 첨가하였다.
멀티 프로그래밍(Multi Programming)
- 여러 개의 프로그램이 동시에 실행된다는 의미로, CPU 사용률을 극대화시킨다.
- 예시: 프로세스 #1 작업을 시작한 후 I/O 작업을 만나면 CPU 가 노는 게 아니라 프로세스 #2 작업을 시작하게 된다. 이후 프로세스 #2 작업을 시작한 후 I/O 작업을 만나면 프로세스 #1 작업을 시작하게 된다.
- 그러나 어느 한 프로그램이 CPU 사용 시간이 길어지면 다른 프로세스는 계속 대기를 해야 한다는 문제점이 존재하였다.
멀티 태스킹(Multi Tasking)
- 프로세스는 CPU 를 사용할 때 짧은 시간만 실행되도록 하여 각 프로그램의 작업을 아주 작은 단위로 번갈아 가며 처리함으로써 작업 응답 시간을 최소화한다.
- CPU 는 잘게 나눈 각 작업을 빠르게 번갈아 가며 수행함으로써 여러 작업을 동시에 처리하는 것처럼 보이게 하여 사용자에게 더 빠른 반응성을 제공한다.
- 작업을 나누었기 때문에 예기치 않은 문제가 발생했을 때 해당 작업만 중지할 수 있어 전체 시스템이 멈추는 것을 방지할 수 있다.
- 멀티 프로세싱 또는 멀티 코어를 사용하는 시스템에서 여러 개의 프로세서(CPU)가 동시에 작업을 효율적으로 처리할 수 있다.
- 프로세스 간의 우선순위 조절이 수월해진다. 우선순위가 높은 작업은 더 자주 실행되어, 더 빠른 처리를 할 수 있다.
- 그러나 응답성을 향상하기 위해 문맥 교환(Context Switching)이 자주 발생하면, 프로세스 간 스위칭 작업이 무거운 작업이기 때문에 오히려 성능 이슈가 발생할 수 있다.
멀티 코어(Multi Core)
- 옛날 컴퓨터의 CPU 는 싱글 코어로, 이 싱글 코어에서 여러 작업을 동시에 처리하기 위해 멀티 태스킹과 같은 기술을 활용하여 작업을 처리했다. 그러나 시대가 발전함에 따라 CPU 코어의 발열 한계로 인해 클럭 속도를 높이지 않고 코어 수를 늘리는 방향으로 듀얼 코어 및 쿼드 코어 CPU 제품이 출시되기 시작했다.
- 한 CPU 에 두 개 이상의 코어를 두어 여러 CPU 코어가 동시에 작업을 처리할 수 있다. 물리적 코어 하나가 스레드 두 개 이상을 동시에 실행 가능하다는 의미이다.
멀티 프로세싱(Multi Processing)
- 하나의 시스템에서 여러 개의 프로세서(CPU)를 사용하여 작업을 처리하는 것
- 여러 개의 프로세서(CPU)가 병렬로 작업을 수행하므로, 단일 프로세스보다 빠른 처리 속도를 보장할 수 있다.
- 멀티 태스킹은 하나의 CPU 에서 여러 개의 작업을 처리하는 반면, 멀티 프로세싱은 여러 개의 CPU 가 각각의 작업을 처리하는 것이라는 차이점이 있다.
멀티 프로세스(Multi Process)
- 하나의 응용 프로그램에 대해 동시에 여러 개의 프로세스를 실행할 수 있는 하는 기술
- 보통 하나의 프로그램 실행에 대해 하나의 프로세스가 메모리에 생성되지만, 부가적인 기능을 위해 여러 개의 프로세스를 생성하는 것이다.
- 하나의 부모 프로세스가 여러 개의 자식 프로세스를 생성하여 다중 프로세스를 구성하는 구조이다.
- 한 프로세스는 실행되는 도중 프로세스 생성 시스템 콜을 통해 새로운 프로세스들을 생성할 수 있는데, 다른 프로세스를 생성하는 프로세스를 부모 프로세스(Parent Process)라 하고, 다른 프로세스에 의해 생성된 프로세스를 자식 프로세스(Child Process)라 한다.
- 부모 프로세스와 자식 프로세스는 각각 고유한 PID(Process ID)를 가지고 있고, 부모 프로세스는 자식 프로세스의 PID 를 알고 있어 자식 프로세스를 제어할 수 있다. 또한, 자식 프로세스는 부모 프로세스의 PID 와 PPID(Parent Process ID)를 알고 있어 부모 프로세스와의 통신이 가능하다.
- 그러나 통신이 가능할 뿐이지, 부모 프로세스와 자식 프로세스는 엄연히 서로 다른 프로세스로 독립적으로 실행되며, 독립적인 메모리 공간을 가지고 있어 서로 다른 작업을 수행한다.
- 예시: 웹 브라우저의 상단 탭(Tab) 이나 새창. 각 브라우저 탭은 같은 브라우저 프로그램 실행이지만, 각기 다른 사이트 실행을 행한다.
- 각 프로세스가 독립적인 메모리 공간을 가지므로, 한 프로세스가 비정상적으로 종료되어도 다른 프로세스에 영향을 주지 않는다. 그래서 프로그램 전체의 안전성을 확보할 수 있다.
- 멀티 태스킹을 구성하는데 핵심 기술인 컨텍스트 스위칭(Context Switching) 과정에서 성능 저하가 올 수 있다.
- 특히 프로세스를 컨텍스트 스위칭 하면, CPU 는 다음 프로세스의 정보를 불러오기 위해 메모리를 검색하고, CPU 캐시 메모리를 초기화하며, 프로세스 상태를 저장하고, 불러올 데이터를 준비해야 하기 때문에, 빈번한 컨텍스트 스위칭이 발생하면 비용 오버헤드가 발생하게 된다.
- 따라서 멀티 프로세스 환경에서는 컨텍스트 스위칭 오버헤드를 최소화는 방법이 중요하다. 이를 위해 프로세스 수를 적절하게 유지하거나, I/O 바운드 작업이 많은 프로세스와 CPU 바운드 작업이 많은 프로세스를 분리하여 관리하며, CPU 캐시를 효율적으로 활용하는 방법을 고려해야 한다.
- 반면 스레드를 컨텍스트 스위칭하면 프로세스 스위칭 보다 가벼워 훨씬 빠르고 좋다.
- 특히 프로세스를 컨텍스트 스위칭 하면, CPU 는 다음 프로세스의 정보를 불러오기 위해 메모리를 검색하고, CPU 캐시 메모리를 초기화하며, 프로세스 상태를 저장하고, 불러올 데이터를 준비해야 하기 때문에, 빈번한 컨텍스트 스위칭이 발생하면 비용 오버헤드가 발생하게 된다.
멀티 스레드(Multi Thread)
- 하나의 프로세스 안에 여러 개의 스레드가 있는 것
- 하나의 프로그램에서 두 가지 이상의 동작을 동시에 처리하도록 하는 행위가 가능하다.
- 예시: 웹 브라우저의 단일 탭 또는 창 내에서 브라우저 이벤트 루프, 네트워크 처리, I/O 및 기타 작업을 관리하고 처리하는 데 사용된다.
- 스레드는 프로세스 보다 용량이 가볍다.
- 스레드는 프로세스 내에서 생성되기 때문에, 스레드의 실행 환경을 설정하는 작업이 매우 간단하며 생성 및 종료가 빠르다.
- 스레드는 프로세스와 달리, 코드, 데이터, 스택 영역을 제외한 나머지 자원을 서로 공유하기 때문에 기본적으로 내장되어 있는 데이터 용량이 프로세스보다 당연히 작다.
- 하나의 프로세스 내에서 여러 개의 스레드를 생성하기 때문에, heap 영역과 같은 공유 메모리에 대해 스레드 간에 자원을 공유가 가능하다. 이를 통해, 프로세스 간 통신(IPC)을 사용하지 않고도 데이터를 공유할 수 있기 때문에 자원을 효율적으로 활용할 수 있으며, 이로 인해 시스템 자원 소모가 줄어든다.
- 스레드에도 컨텍스트 스위칭 오버헤드가 존재한다. 하지만 상대적으로 프로세스 컨텍스트 스위칭 오버헤드보다 훨씬 비용이 낮다.
- 스레드 컨텍스트 스위치 비용은 스위칭할 때 스레드 간에 공유하는 자원을 제외한 스레드 정보(stack, register)만을 교체하면 되기 때문에 상대적으로 낮다.
- 그러나 스레드 수가 많으면 많을 수록 그만큼 컨텍스트 스위칭이 많이 발생하게 되고 당연히 이는 성능 저하로 이어진다. 스레드가 많을수록 작업을 분리해서 동시에 처리하니까 항상 빠르다는 고정 관념을 깨는 것이 중요하다.
- 스레드 컨텍스트 스위치 비용은 스위칭할 때 스레드 간에 공유하는 자원을 제외한 스레드 정보(stack, register)만을 교체하면 되기 때문에 상대적으로 낮다.
- 하나의 스레드에서 문제가 발생하면, 다른 스레드들도 영향을 받아 전체 프로그램이 종료될 수 있다.
- 스레드에 에러가 발생할 경우, 적절한 예외 처리를 통해 이를 관리하거나, 에러 발생 시 새로운 스레드를 생성하거나 스레드 풀(Thread Pool)에서 잔여 스레드를 가져와 프로그램 종료를 방지할 수 있다.
- 그러나 이때 새로운 스레드 생성이나 놀고 있는 스레드 처리에 추가 비용이 발생하게 된다.
- 스레드에 에러가 발생할 경우, 적절한 예외 처리를 통해 이를 관리하거나, 에러 발생 시 새로운 스레드를 생성하거나 스레드 풀(Thread Pool)에서 잔여 스레드를 가져와 프로그램 종료를 방지할 수 있다.
- 여러 개의 스레드가 공유 자원에 동시에 접근할 수 있기 때문에 동기화 문제가 발생한다.
- 동기화 작업은 여러 스레드가 자원에 대한 접근을 순차적으로 통제하여, 동시 접근으로 인한 데이터 수정과 같은 현상이 발생하지 않도록 한다.
- 그러나 동기화 작업은 여러 스레드 접근을 제한하는 것이기 때문에 병목 현상이 일어나 성능이 저하될 가능성이 높다.
- 이를 해결하기 위해 *임계 영역에 대하여 뮤텍스(Mutex), 또는 세마포어(Semaphore) 방식을 활용한다.
- 임계 영역(Critical Section) : 공유 자원을 접근하는 코드 영역. (전역 변수, heap 메모리 영역 등)
- 그러나 뮤텍스나 세마포어와 같은 동기화 기법은 스레드가 데이터에 접근하기 전에 락(Lock)을 획득하고, 데이터에 접근한 후에 락을 해제하는 데, 이러한 락 획득 및 해제 작업은 추가적인 시간이 소요되며, 나머지 스레드의 실행을 중지하거나, 대기하게 만들어야 하므로 프로그램의 성능이 저하될 수 있다.
- 이를 해결하기 위해 *임계 영역에 대하여 뮤텍스(Mutex), 또는 세마포어(Semaphore) 방식을 활용한다.
- 그러나 동기화 작업은 여러 스레드 접근을 제한하는 것이기 때문에 병목 현상이 일어나 성능이 저하될 가능성이 높다.
- 동기화 작업은 여러 스레드가 자원에 대한 접근을 순차적으로 통제하여, 동시 접근으로 인한 데이터 수정과 같은 현상이 발생하지 않도록 한다.
- 다수의 프로세스나 스레드가 서로 자원을 점유하고, 다른 프로세스나 스레드가 점유한 자원을 기다리는 상황에서 발생하는 교착 상태, 데드락(Deadlock)이 발생할 수 있다.
- 공유 자원에 대한 동시 엑세스로 인한 문제로, 이를 방지하기 위한 상호배체(Mutual Exclusion), 점유와 대기(Hold and Wait), 비선점(No Preemption), 순환 대기(Circular Wait) 등의 알고리즘을 통해 극복해야 한다.
'안드로이드 > etc.' 카테고리의 다른 글
[CS] 비트(bit)와 바이트(byte), 음수 표현법 (0) | 2024.11.27 |
---|---|
[CS] 블록체인(Blockchain) (0) | 2024.11.25 |
[Kotlin] 에러(Error)와 예외(Exception) (0) | 2024.11.20 |