프로세스는 CPU(프로세서)에 의해 실행되는 프로그램이다.
그림으로 보면 아래와 같다.
프로그램은 application 개발자가 작성한 코드이다. 프로그램은 실행이 되지 않는다면 그냥 데이터의 집합일 뿐이다.
이 프로그램을 작동 시키려면 CPU(프로세서)에서 코드를 읽고 명령어를 실행 시켜야한다. 하지만 현대의 거의 모든 컴퓨터들은 폰노이만 구조를 하고 있기 때문에 디스크에 있는 프로그램을 바로 CPU로 전달할 수 없다. 그래서 메인 메모리에 프로그램을 올리고 메모리에서 코드들을 한줄씩 CPU에 전달하여 실행 하게된다. 이렇게 메모리에 올려저서 실행 중인 프로그램을 프로세스라고 한다. (메모리에 올라간 것 자체가 실행 준비 상태로 볼 수 있기 때문에 메모리에 올라가는 자원 할당 단위를 프로세스로 보기도 한다.)
프로세스 : 메모리에 올려져서, 실행 중인 프로그램
프로그램 : 개발자가 작성한 코드 묶음.
프로세서 : CPU
CPU는 한번에 하나의 프로세스만을 실행한다. 예전의 컴퓨터는 이러한 이유로 하나의 프로세스를 실행하고 있을 때, 다른 프로세스는 실행하지 못했다. 즉, 게임을 하면서 카톡을 할 수 없었다. 하지만 요즘 컴퓨터는 한번에 여러 프로세스를 실행할 수 있다. 이것을 가능하게 해주는 것이 멀티 태스킹이다.
멀티 태스킹이란 하나의 CPU에서, 여러 응용 프로그램이 동시에 실행되는 것처럼 보이도록 하는 시스템이다.
멀티 태스킹은 위 사진과 같은 스케줄링 알고리즘을 가진다.
각 프로세스의 응답 시간을 최소화하기 위하여 프로세스들을 엄청나게 잘게 쪼개서(ms 단위까지 쪼갬) 계속 번갈아가며 실행 시키는 알고리즘이다. 그래서 우리의 눈에는 동시에 여러 프로세스가 실행되는 것처럼 보이는 것이다.
그리고 이렇게 여러 프로세스를 번갈아가면서 실행 시키는 과정을 컨텍스트 스위칭이라고 한다.
컨텍스트 스위칭을 하고 프로세스가 다시 실행이 될 때 어디서부터 다시 실행하는지(PC, SP 정보), 프로세스의 상태(생성, 준비 실행, 대기, 종료) 등을 알아야 한다. 그래서 이 정보들을 PCB라는 메모리 공간에 저장을 해두고 컨텍스트 스위칭을 할 때마다 여기서 읽어오게 된다.
프로그램이 고도화 될 수록 멀티 태스킹은 몇가지 단점들이 있다.
1. 하나의 프로세스가 동시에 여러 작업을 수행하지 못함.
하나의 프로세스가 하나의 작업 밖에 하지 못하므로 속도의 아쉬움이 있다. 물론 하나의 프로그램을 여러 프로세스로 띄워서 성능을 높일 수 있겠지만 이 다음과 같은 한계는 극복하지 못한다.
2. 프로세스의 컨텍스트 스위칭은 무거운 작업이다.
컨텍스트 스위칭이 되면, 이전의 프로세스의 상태를 PCB에 보관하고, 새로운 프로세스의 상태를 PCB에서 읽어와 CPU 내에 있는 레지스터에 적재해야한다. 그러므로 이는 시스템에 많은 부담을 준다.
3. 프로세스끼리 데이터 통신이 까다로움.
프로세스는 독립적인 메모리 공간을 가진다. 만약 하나의 프로그램을 여러 프로세스로 실행 시킨다면 프로세스끼리 데이터를 통신을 해야하는 경우가 반드시 있다. 물론 IPC라는 프로세스 간 데이터 통신 기법을 사용할 수 있지만 이것도 굉장히 번거로운 작업이다.
4. 듀얼 코어 CPU가 등장했지만 잘 활용하지 못함.
하드웨어적으로는 듀얼 코어가 나왔지만 기존 멀티 태스킹 방식으로는 듀얼 코어의 장점을 100% 살리지 못함.
이러한 단점들을 보완하기 위해 나온 것이 스레드라는 개념이다.
적은 범위에서 얘기하면 스레드(thread)는 프로세스 내에서 실행되는 작업 흐름의 단위를 말한다. 더 확장되어 CPU에서 실행되는 단위이다.
위 그림은 하나의 프로세스가 멀티 스레드일 때의 데이터 구조이다.
위의 프로세스의 단점을 많이 보완하기위해 나왔고, 병렬적인 작업을 가능하게 해준다.
1. 프로세스는 두 개 이상의 스레드를 가질 수 있다.
그래서 병렬적으로 작업을 처리할 수 있다.
2. 같은 프로세스에 있는 스레드들끼리 컨텍스트 스위칭이 가볍다.
스레드는 위 사진처럼 data 등을 공유하고 있고 stack, register block 영역만 나눠져있기 때문에 그 부분만을 CPU 레지스터에 교체해주면 된다. 그러므로 프로세스 간의 컨텍스트 스위칭보다 비용이 훨씬 적다.
3. 스레드간 데이터 통신이 쉽다.
위 사진처럼 스레드들은 자신들이 속한 프로세스의 메모리 영역 (data, code 영역 등)을 공유하고 있기 때문에 통신할 데이터를 이 공유 영역에 올리기만 하면 된다. 프로세스처럼 IPC같은 특별한 기법이 필요하지 않다.
가끔 글들을 보면 멀티 태스킹과 멀티 프로세싱을 혼용하는 것 같아서 정리를 해보았다.
위의 사진에서 cpu부분을 cpu의 코어라고 보는 것이 맞다.
멀티 코어 CPU가 있을 때 코어마다 하나의 프로세스나 스레드를 할당하는 것이다.
이러한 경우 멀티 코어의 활용도를 높일 수 있다.
앞서 멀티 태스킹은 여러 프로세스를 아주 짧게 쪼개진 단위로 나누어 번갈아 실행하는 것을 의미했지만 스레드라는 개념이 생기며 여기에 스레드도 추가가 되었다. 즉, 여러 프로세스와 여러 스레드가 아주 짧게 쪼개진 단위로 나누어 번갈아 실행되는 것을 의미한다.
1. 스레드 중 한 스레드만 문제가 있어도, 전체 프로세스가 영향을 받음.
멀티 프로세스 환경에서는 하나의 프로세스가 죽어도 다른 프로세스에 대부분의 경우 영향을 미치지 않는다. 하지만 멀티 스레드의 경우 하나의 스레드가 죽으면 전체 프로세스가 죽는 경우가 많다.
2. 동기화 이슈로 비정상적으로 동작 가능
스레드의 가장 큰 단점이다. 이는 데이터를 공유하기 때문에 발생하는 문제인데, 간단하게 얘기하면 두 개 이상의 스레드가 하나의 데이터에 접근하려고 할 때 우리가 기대한 동작과는 다르게 발생하는 상황이다. 동기화 이슈는 나중에 다른 게시물로 올려보려고한다.