Process
운영체제는 사용자의 요청을 받으면 프로그램을 찾아서 실행시켜주는 역할을 합니다. 이러한 프로그램을 프로세스라고 합니다.
프로세스 구조
프로세스는 위의 그림과 같은 구조를 갖고 있습니다.
- 코드 영역은 컴파일된 소스 코드가 저장되는 영역입니다.
- 데이터 영역은 전역 변수와 초기화된 데이터가 저장되는 영역입니다.
- 힙 영역은 코드에서 동적으로 생성되는 데이터가 저장되는 영역입니다.
- 스택 영역은 지역 변수와 매개 변수 등이 저장되는 영역입니다.
운영체제에서는 웹 브라우저와 엑셀, 멜론 플레이어, 카카오톡 등 다양한 프로세스를 실행하고 있습니다.
보통 컴퓨터를 사용할 때는 하나의 프로세스만 사용하는 경우는 없습니다. 많은 프로세스를 사용하게 되는데, 운영체제는 어떻게 여러 프로세스들을 동시에 실행할 수 있을까요?
Multi process (Multi tasking)
운영체제는 CPU를 통해서 여러 프로세스들을 실행시킬 수 있도록 합니다. 이것을 멀티 태스킹 또는 멀티 프로세스라고 합니다.
엄밀히 따지면, 여러 프로세스들을 동시에 실행하는 것이 아니라 동시에 실행하는 것처럼 보이는 것입니다. 이를 동시성(Concurrency)이라고 합니다.
CPU가 각각의 프로세스를 동시에 이용하는 것처럼 보이기 위해서 프로세스가 CPU를 점유하는 시간을 잘게 분할하는데, 이것을 시분할 방식이라고 합니다.
단, CPU의 코어가 여러 개라면 그 개수 만큼은 프로세스를 (진짜) 동시에 실행할 수 있습니다. 이것을 병렬성(Parallelism)이라고 합니다. 이 글에서는 병렬성보다 동시성에 집중하여 설명을 드리겠습니다.
Context switching
앞서 언급한 것처럼 CPU는 여러 프로세스를 동시에 실행하는 것처럼 보이기 위해 시분할 방식으로 CPU를 점유하는 시간을 잘게 나눕니다.
이때 잘게 나눈 시간을 기준으로 CPU를 점유하는 프로세스가 빠르게 바뀌게 됩니다. CPU를 점유하는 프로세스가 빠르게 바뀔 때, 각 프로세스마다 수행 상태를 기억하기 위해 실행 상태를 구성하는 정보를 컨텍스트라는 객체에 저장합니다. 그리고 위의 그림처럼 컨텍스트가 계속해서 바뀐다 하여 이를 컨텍스트 스위칭이라고 합니다.
Synchronous vs Asynchronous
컨텍스트 스위칭이 일어난다는 것은 컨텍스트가 여러 개라는 말입니다. 이렇게 컨텍스트 여러 개가 교환이 일어나는 것을 비동기 방식이라고 합니다.
반면, 동기 방식은 하나의 컨텍스트로 작업들을 하나씩 완료해 나가는 것을 말합니다.
Process context switching 문제점
프로세스 간 컨텍스트 스위칭의 문제점을 이해하면, 왜 스레드가 등장했는지 알 수 있습니다.
스레드라는 개념이 없다고 가정하고, 위의 그림처럼 카카오톡에서 채팅을 하면서 파일을 다운로드하는 상황으로 설명을 하겠습니다.
자식 프로세스가 많아지면서 생기는 독점 현상
카카오톡 프로세스에서 채팅 프로세스와 파일 다운로드 프로세스를 띄우게 됩니다.
이러한 상황에서 시분할 방식으로 컨텍스트 스위칭을 한다면, 형평성에 어긋나는 일이 발생하게 됩니다.
만약 카카오톡 프로세스에서 100개의 자식 프로세스가 실행된다면, 카카오톡 프로세스가 CPU를 상대적으로 많이 점유하는 일이 발생하게 됩니다.
프로세스 간 자원 공유 불가, 컨텍스트 스위칭 비용 증가
멀티 프로세스 구조
위의 그림처럼 프로세스 간에는 자원을 공유할 수 없습니다.
카카오톡 프로세스와 멜론 프로세스는 서로 자원을 공유할 일이 없어서 문제 없지만, 카카오톡 프로세스 안의 채팅 프로세스와 파일 다운로드 프로세스는 서로 공유해야 하는 자원이 있을 수 있습니다.
또한, 공유 자원을 사용하지 않기 때문에 컨텍스트 스위칭 비용이 많이 들게 됩니다. 그래서 프로세스 안에 자식 프로세스가 많아지게 된다면, 시간이 오래 걸리게 됩니다.
이처럼 위의 문제점들을 개선하기 위해서 등장한 개념이 스레드입니다.
Thread
스레드는 프로세스 내에서 작업을 수행하는 주체를 의미합니다.
보통 하나의 프로세스에는 2개 이상의 스레드를 갖고 있습니다. 이를 멀티 스레드라고 합니다.
위에서 설명한 자식 프로세스의 역할을 스레드가 할 수 있고, 멀티 스레드 구조를 갖는 프로세스를 통해서 위의 문제점들을 해결할 수 있습니다.
멀티 스레드 구조
코드 영역과 데이터 영역, 힙 영역을 공유자원이라고 합니다. 스레드는 프로세스와 달리 공유 자원의 영역을 독자적으로 갖고 있지 않고 프로세스 내에서의 공유자원을 이용합니다.
프로세스 간의 컨텍스트 스위칭을 할 때는 공유자원도 스위칭해야 해서 비용이 많이 들었지만, 스레드 간의 컨텍스트 스위칭은 공유 자원을 제외하고 스위칭하기 때문에 상대적으로 비용이 적게 들게 됩니다.
또한, 시분할 방식으로 각 프로세스에게 주어진 시간을 프로세스 안의 스레드들끼리 나누어서 사용하기 때문에, 한 프로세스가 CPU를 독점하는 일도 해결할 수 있습니다.
Thread context switching 문제점
멀티 스레드 환경에서 컨텍스트 스위칭이 발생할 때도 문제점이 없는 것은 아닙니다. 한 프로세스 안의 공유자원을 각 스레드가 사용하기 때문에 데이터가 원하는 방향으로 흘러가지 않을 수 있기 때문입니다.
이러한 문제로 인해서 프로그래밍을 할 때, 멀티 스레드 환경에서 동시성을 제어하는 일이 중요해지게 된 것입니다.
다음에는 소스 코드를 통해서 동시성을 제어할 수 있는 방법을 설명하도록 하겠습니다. 이상입니다. 수정 사항이나 피드백이 있으시다면 편하게 댓글 부탁드리겠습니다. 글 읽어 주셔서 감사합니다