woowacourse-study / 2022-cs-plant

cs 씨앗을 심기 위한 repository 입니다.
7 stars 1 forks source link

프로세스와 스레드 #1

Open hyeonic opened 2 years ago

hyeonic commented 2 years ago

프로세스와 스레드

프로그램과 프로세스

프로그램은 우리가 구현한 코드 파일을 모아둔 것이다. 이러한 프로그램을 실행하기 이전에는 단순한 코드 파일에 불과하다. 이것을 사용하기 위해서는 실행이 되어 사용할 수 있는 무언가가 되어야 한다.

image

이러한 프로세스는 생성될 때 프로세스의 정보를 가진 PCB가 함께 생성된다.

프로세스, 스레드

어떤 관리의 단위이다. 이 관리의 주체는 바로 운영체제이다. 프로세스는 기본적으로 연산할 것들을 모아둔 것이다. 프로세스는 이러한 흐름(flow, context)이 기본적으로 한 개 가지고 있다. 기본적으로 프로세스 하나가 존재한다면 내부에 스레드도 한 개 존재한다.

만약 이러한 흐름이 n개가 되면 어떻게 될까? 한 프로세스 내부에 여러 개의 흐름이 존재할 수 있다는 것을 의미한다. 또한 동시에 각자 작동한다. 프로세스에서 개별화된 각각의 코드 실행 흐름을 스레드라 한다. 이 스레드가 한 프로세스 내에서 여러 개인 경우 이것을 멀티 스레딩이라고 한다.

프로세스가 연산을 하기 위해서는 CPU와 연습장을 담당하는 RAM이 필요하다. 그렇기 때문에 RAM의 일정 부분을 할당해주어야 한다. 운영체제는 프로세스가 사용할 메모리를 가상 메모리로 지정 해준다. 가상 메모리로 인해 물리 메모리에 직접 접근하는 것을 막는다. 가상 메모리는 1차(RAM), 2차(HDD, SSD 등) 메모리를 적절히 추상화하여 만들어준다. 핵심은 가상 메모리 공간을 운영체제가 프로세스에게 할당해준다는 것이다.

프로세스(작업)는 최소 1개의 스레드를 가진다. 즉 무엇을 연산하는 행위는 스레드 단위로 진행된다. 운영체제는 가상 메모리(Virtual Memory)를 프로세스에게 할당한다. 프로세스는 운영체제로 부터 제한된 공간을 할당 받는 것이다. 프로세스에 속한 모든 스레드는 프로세스의 가상 메모리로 공간이 제약된다.

스레드는 실질적 연산을 실행하는 주체이다. 멀티 스레딩 환경에서는 한정된 메모리를 함께 공유하여 사용하기 때문에 동시성, 동기화 이슈가 생긴다.

각각의 스레드는 각자 고유한 공간을 가지고 있다. 이 메모리를 Thread Local Storage라 부르며 Stack 메모리 구조를 가지고 있다. 이러한 스레드들은 Heap이라는 공용 공간을 함께 사용한다.

이 밖에도 프로세스와 스레드는 아래와 같은 메모리 영역을 가진다.

image

image

멀티 프로세스

하나의 애플리케이션에서 여러 가지 일을 처리하는 경우가 있다. 간단히 예로 웹 애플리케이션이 여러 요청을 처리하는 것을 생각할 수 있다.

한 프로세스만 가진 경우 매번 하나의 요청만 처리할 수 있기 때문에 동시에 여러 요청을 처리할 수 없다. 그렇기 때문에 부모 프로세스를 fork하여 자식 프로세스를 여러 개 만들어 요청을 처리한다. 이때 각각의 프로세스는 개별 메모리를 운영체제에게 할당 받는다.

앞서 언급한 것처럼 각각의 프로세스는 독립적이며 프로세스간 통신을 위해서도 (IPC, inter-process communication)을 사용해야 한다. 또한 각각의 개별 메모리를 가지고 있기 때문에 컨텍스트 스위칭이 일어날 때도 많은 비용이 소모될 수 있다. 다만 각각의 요청을 개별 프로세스가 진행하기 때문에 메모리에 대한 동기화 작업에서 조금은 자유로워진다.

멀티 스레드

하나의 프로세스 내에서 여러 실행 흐름을 처리할 수 있도록 다수의 스레드를 가질 때 이것을 멀티 스레드라고 한다. 스레드는 프로세스 내의 자원을 공유해서 사용하고 있다. 이러한 공유 자원 덕분에 스레드 간 데이터 통신 비용이 절약된다. 또한 컨텍스트 스위칭이 일어날 때도 프로세스에 비해 적은 비용이 발생한다. 다만 공유 자원에 동시에 접근할 경우 다양한 문제가 발생할 수 있기 때문에 공유 자원에 대한 관리가 필요하다.

Java에서 스레드

JVM은 단일 프로세스에서 실행되며 멀티 스레드 환경을 지원한다. Java에서 스레드는 전적으로 JVM에 의해 관리된다. 프로세스가 실행되기 위해서는 적어도 하나 이상의 스레드가 필요하다. Java는 main() 메서드를 기반으로 메인 스레드가 시작된다.

그래서 뭐가 더 좋은 건가?

지금 까지 하나의 애플리케이션이라 가정한 뒤 멀티 프로세스와 멀티 스레드에 대한 설명을 나열한 것이다. 멀티 프로세스와 멀티 스레드는 모두 처리 방식의 일종이다. 뚜렷하게 무엇이 좋다라고 단정할 수 없다. 각각의 처리 방식이 모두 장단점을 가지고 있기 때문이다. 만약 멀티 스레드로 개발된 웹 브라우저가 있다고 가정한다. 하나의 스레드에서 오류가 발생할 경우 프로세스 내에 모든 스레드에게 영향이 갈 수 있다. 멀티 프로세스로 개발된 웹 브라우저의 경우 하나의 프로세스에서 문제가 생길 때 프로세스 간에 영향을 줄일 수 있다.

멀티 코어

멀티 프로세스와 멀티 스레드는 처리 방식이기 때문에 소프트웨어 분야에 가깝다. 멀티 코어는 하드웨어에 가까운 개념이다.

하나의 코어를 가진 경우 동시에 여러 실행 흐름 처리를 위해 빠른 주기로 전환이 되어 실행된다. 이로 인해 동시에 처리하는 것 처럼 보여지는데, 이것을 동시성(Concurrency)이라 한다.

멀티 코어는 여러 코어를 사용하여 다수의 실행 단위를 한 순간에 동시에 처리할 수 있는데, 이것을 병렬처리(Parallelism)라고 한다.

예상 질문

References.

hyeonic commented 2 years ago

프로세스 간의 컨텍스트 스위칭 보다 스레드 간의 컨텍스트 스위칭 비용이 적은 이유는 무엇인가요?