- Published on
프로세스와 스레드
- Authors
- Name
- Na Hyunwoo
위키피디아에서는 프로세스를 다음과 같이 정의하고 있습니다. 컴퓨터에서 실행되고 있는 컴퓨터 프로그램. 이렇게 들으면 뭔가 와닿지 않습니다. 그래서 프로그램이 뭔데 ?
프로그램
프로그램이란, 파일이 저장 장치에 저장되어 있지만 메모리에는 올라가 있지 않은 정적인 상태를 말합니다.
이 정의를 풀어서 설명해보면,
메모리에는 올라가 있지 않은 → 운영체제가 아직 프로그램에게 독립적인 메모리 공간을 할당해주지 않았다는 뜻입니다. 모든 프로그램은 운영체제가 실행되기 위한 메모리 공간을 할당해줘야 실행될 수 있습니다.
정적인 상태 → 실행되지 않고 가만히 있는 상태라는 의미입니다.
즉, 프로그램은 실행하기 전 파일 그 자체를 의미합니다. *.png 파일과 같은 것의 실행하기 전의 파일을 말합니다. 코드에 비유하자면 그냥 코드 덩어리라고 할 수 있습니다.
프로세스
그럼 이 프로그램을 실행하면 어떻게 될까요 ? 프로그램을 실행하는 순간 이 파일은 컴퓨터 메모리에 올라갑니다. 그러면 이제 이 파일은 동적인 상태가 됩니다. 그리고 이 실행중인 프로그램을 프로세스라고 합니다.
저의 어렸을 적 기억에 빗대어 예를 들어보겠습니다. 저는 어렸을 때 게임을 상당히 좋아해서 방과후에 집에 오자마자 컴퓨터를 켜고 조금이라도 더 빨리 게임을 하기 위해 인터넷 익스플로러를 마구잡이로 눌렀습니다. 이 때, 인터넷 익스플로러 파일은 프로그램이고 더블 클릭을 한 후에 뜨는 창이 프로세스인 것입니다. 만약 저처럼 더블클릭을 여러번 했다면 인터넷 창이 여러개가 뜨는데, 이 말은 하나의 프로그램에 여러개의 프로세스가 생성이 가능하다는 말입니다. 너무 많은 프로세스가 생겨 작업 관리자를 통해 모든 프로세스를 종료시키기도 했었지요.
다음은 프로그램과 프로세스를 나타낸 그림입니다.
요약하자면, 프로그램은 코드 덩어리 파일이고 이 프로그램을 실행하면 프로세스입니다.
스레드
과거에는 프로그램을 실행하면 시작부터 끝까지 하나의 프로세스만을 사용했다고 합니다. 하지만 기술이 발전할수록 프로그램은 복잡해짐에 따라 하나의 프로세스만을 사용하는 것을 불가능하게 되었습니다. 이를 해결하기 위해 어떻게 했을까요 ?
이 문제를 해결하기 위해 등장한 개념이 스레드입니다.
스레드는 프로세스의 특정한 수행 경로입니다. 또한 스레드는 프로세스와 다르게 스레드 간 메모리를 공유하며 동작합니다.
프로그램이 코드 덩어리라면, 스레드는 코드 내에 선언된 함수라고 할 수 있습니다. 따라서 main함수 또한 일종의 스레드라고 할 수 있습니다.
스레드는 프로세스의 코드에 정의된 절차에 따라 실행되는 특정한 수행 경로이다.
프로세스와 스레드 딥다이브
프로세스
프로세스는 메모리에 올라갈 때 운영체제로부터 시스템 자원을 할당받습니다. 이 때 운영체제는 프로세스마다 독립된 메모리 영역을 다음 그림과 같이 Code, Data, Stack, Heap의 영역으로 할당해줍니다.
위해서 말했듯이, 프로세스는 독립된 메모리 영역을 할당받기 때문에 다른 프로세스의 자료에 접근할 수 없습니다.
스레드
이와 다르게 스레드는 메모리를 서로 공유할 수 있습니다. 프로세스가 할당받은 메모리 영역 내에서 Stack 형식으로 할당된 메모리 영역은 따로 할당받고, 나머지 Code, Data, Heap 형식으로 할당된 메모리 영역을 공유합니다.
여기서 프로세스와 스레드의 중요한 차이가 있습니다. 만약 한 프로세스를 실행하다가 오류가 발생해서 프로세스가 강제로 종료되면 프로세스는 독립적인 공간을 할당받기 때문에 다른 프로세스에게 영향을 주지 않습니다. 반면에 스레드는 메모리 영역을 공유하기 때문에 어떤 스레드 하나에서 오류가 발생한다면 한 프로세스 안에 있는 다른 스레드들 모두 강제로 종료됩니다.
싱글 스레드
하나의 프로세스를 하나의 스레드를 사용하여 처리하는 것을 의미합니다.
멀티 스레드
하나의 프로세스를 여러 스레드를 사용하여 동시에 처리하는 것을 의미합니다.
멀티 스레드의 장단점을 얘기하기 전에 context switching을 알아야 합니다.
context switching이란 현재까지의 작업 상태나 다음 작업에 필요한 각종 데이터를 저장하고 읽어오는 작업을 가리킵니다.
스레드가 서로 교체될 때 스레드간의 문맥 교환이 일어납니다.
싱글 스레드 vs 멀티 스레드
싱글 스레드 장점
- 동기화 작업이 필요하지 않습니다.
- context switching이 필요하지 않아 전환 비용이 발생하지 않습니다.
싱글 스레드 단점
- 하나의 스레드에서 함수가 실행되는 동안 다른 함수의 실행을 확인할 수 없기때문에 동시성의 장점을 누리기 어렵습니다.
멀티 스레드 장점
- 여러개의 스레드를 통해 작업을 동시에 처리할 수 있습니다. 따라서 작업시간을 단축시킬 수 있습니다.
멀티 스레드 단점
- 스레드 하나가 프로세스 내 자원을 망친다면 모든 프로세스가 종료될 수 있습니다.
- 자원을 공유하기 때문에 동기화 문제가 발생합니다.
- 프로그래밍이 어렵습니다.
여기서 동기화 문제란 어떤 것일까요 ?
동기화 문제란 멀티 스레드를 사용하면 A 스레드가 어떤 자원을 사용하다가 B 스레드로 제어권이 넘어간 후, B 스레드에서 해당 자원을 수정하고 다시 제어권을 A로 넘겼을 때, A 스레드가 바뀐 자원에 접근하면서 발생하는 오류를 뜻합니다.
공부하며 생긴 의문들
스레드들은 같은 프로세스를 공유하기 때문에 메모리를 공유할 수 없다. 근데 스택은 왜 독립적으로 할당되는 것일까 ?
스택은 함수 호출 시 전달되는 인자, 되돌아갈 주소값 및 함수 내에서 선언하는 변수 등을 저장하기 위해 사용되는 메모리 공간이다. 따라서 스택 메모리 공간이 독립적이라는 것은 독립적인 호출이 가능하다는 것이고, 이는 독립적인 실행 흐름이 추가되는 것이다. 결과적으로 실행 흐름의 추가를 위한 최소 조건이 독립된 스택을 제공하는 것이다.
멀티 스레드가 정말로 동시성을 가지고 작업을 처리하는 것일까 ? 일종의 자바스크립트의 이벤트 루프처럼 동시성을 가지고 진행하는 것처럼 보이게 하는 것은 아닐까 ?
최근에 공부한 이벤트 루프와 개념이 겹쳐보여서 헷갈렸습니다. 멀티 스레드는 정말로 병렬적으로 실행 흐름이 진행되는 것입니다.