프로그램과 프로세스의 개념
프로그램(program)과 프로세스(process), 쓰레드(thread)의 개념을 명확히 알기 위해서는 우선 컴퓨터의 구조를 이해할 필요가 있다. 컴퓨터를 이루는 주요 구성 요소로는 중앙 처리 장치(CPU), 메모리(memory) 그리고 하드디스크(hard disk)로 총 3가지가 있다. 이 중에 CPU는 연산을 수행함으로써 실제 프로그램을 실행하는 장치로, 세 구성 요소중 가장 빠른 속도로 동작한다. 반면에 데이터의 저장 역할을 수행하는 하드디스크는 상대적으로 가장 낮은 속도로 동작한다.
CPU와 하드디스크의 속도 차이는 매우 크기때문에 하드디스크에 저장된 데이터가 CPU로 바로 이동된다면 CPU의 처리 속도는 하드디스크의 느린 속도에 맞춰질 것이다. 따라서 중간에 데이터를 전달하는 역할이 필요한데, 이것이 메모리의 역할이다. 메모리의 속도는 CPU보다 느리지만, 거의 근접한 속도로 동작할 수 있다. 따라서 실제 하드디스크에 저장된 프로그램이 실행되기 위해서는 먼저 프로그램을 메모리로 로딩(loading)하는 과정을 거쳐 프로세스 상태로 만들어야 한다. 그리고 메모리의 로딩된 프로세스는 CPU와 비슷한 속도로 CPU와 대화하며 프로그램을 실행하게 된다.
위의 내용을 정리하면 프로그램은 하드디스크에 저장된 파일들의 모임, 프로세스는 메모리상에 로딩된 프로그램을 의미한다. 그리고 메모리는 프로그램 전체를 한꺼번에 로딩하는 것이 아니라 그때그때 필요한 부분만을 동적으로 로딩한다.이 때 동일한 프로그램을 메모리에 2번 로딩하면 2개의 프로세스가 동작하는데, 이를 멀티 프로세스(multi-process)라고 한다. 예를 들어 파워포인트 파일을 2개 열면 파워포인트 프로그램이 메모리에 2번 로딩돼 멀티 프로세스로 동작한다.
쓰레드의 개념
앞에서 CPU는 하드디스크와의 속도 차이때문에 비슷한 속도로 동작할 수 있는 프로세스와 대화한다고 했다. 이 부분을 좀 더 자세히 보면 실제 CPU를 사용하는 것은 프로세스 내부의 쓰레드이다. 프로세스가 쓰레드를 갖고 있으므로 외부에서 보면 프로세스가 CPU를 사용하는 것처럼 보이게 된다. 그리고 쓰레드를 포함하고 있지 않은 프로세스는 없으며, 쓰레드는 'CPU를 사용하는 최소 단위'라고 할 수 있다.
자바 프로그램에서의 쓰레드
.class 파일을 실행하면 자바 가상 머신은 main 쓰레드를 생성한다. 그리고 main() 메서드에서 작성한 내용이 이 main 쓰레드에서 동작한다. 만약 main 쓰레드의 내부에서 2개의 쓰레드를 생성해서 실행하면 동시에 2개 이상의 쓰레드가 동작하게 되는데, 이를 멀티 쓰레드(multi-thread) 프로세스라고 한다.
멀티 쓰레드의 필요성
쓰레드는 CPU를 사용하는 최소 단위라고 할 수 있다. 그렇다면 멀티 쓰레드는 2개 이상의 쓰레드가 동시에 CPU를 사용한다는 의미인데, 이렇게 멀티 쓰레드가 필요한 이유를 간단한 예시를 통해 알아보자.
우리가 외국 영화나 드라마를 볼 때, 비디오 프레임에 맞춰 자막이 올바른 타이밍에 출력돼야 할 것이다. 그런데 아래 코드와같이 단일 쓰레드(single-thread)에서 반복문이 순차적으로 실행된다면 비디오 프레임이 모두 출력된 후에 자막이 출력될 것이다. 이러한 문제를 해결할 수 있는 것이 멀티 쓰레드이다.
public class SingleThread1 {
public static void main(String[] args) {
// 비디오 프레임 1~5
int[] intArray = {1, 2, 3, 4, 5};
// 자막
String[] strArray = {"하나", "둘", "셋", "넷", "다섯"};
//비디오 프레임 출력
for (int i = 0; i < intArray.length; i++) {
System.out.println("비디오 프레임: " + intArray[i]);
try {
Thread.sleep(200);
} catch (InterruptedException e) {}
}
// 자막 출력
for (int i = 0; i < strArray.length; i++) {
System.out.println("자막: " + strArray[i]);
try {
Thread.sleep(200);
} catch (InterruptedException e) {}
}
}
}
쓰레드의 동시성과 병렬성
비디오 프레임과 자막이라는 2개의 작업이 동시에 수행되기 위해서는 멀티 쓰레드를 사용한다고했는데, 내 컴퓨터에 하나의 CPU만 있는데 어떻게 쓰레드가 동시에 여러개가 실행되는걸까? 이에 대해서는 쓰레드의 동시성(concurrency)과 병렬성(parallelism)을 이해하면 의문을 해결할 수 있다.
우선 단일 쓰레드를 사용해서 2개의 작업을 처리할 때 각 작업은 순차적으로 처리된다. 하지만 멀티 쓰레드에서는 동시성 또는 병렬성을 갖고 작업들을 처리할 수 있다.
동시성은 처리할 작업의 수가 CPU의 코어 수보다 많을 때 적용된다. 예를 들어서 CPU의 코어는 1개인데, 동시에 처리해야 할 작업이 2개일 때, CPU는 각 작업 쓰레드의 요청 작업을 번갈아가면서 실행한다. 매우 짧은 간격으로 교차 실행하기 때문에 사용자는 두 작업이 마치 동시에 실행되는 것처럼 보인다. 이것을 쓰레드의 동시성이라고 말한다. 따라서 정확히 말하자면 동시성은 두 작업이 동시에 실행되는 거이 아니라 동시에 실행되는 것처럼 보이도록 하는 방식이다.
병렬성은 CPU의 코어 수가 작업 수보다 많을 때 적용될 수 있다. 각각의 작업을 각각의 코어에 할당해서 동시에 실행할 수 있기 때문에 말그대로 동시에 작업이 수행된다.이를 쓰레드의 병렬성이라고 말한다.
만약 작업 수가 4개, 코어가 2개라면 쓰레드의 동시성과 병렬성이 함께 적용된다. 먼저 작업이 2개의 코어에 나뉘어 할당되고(병렬성), 각각의 코어는 할당된 작업을 번갈아 실행할 것이다.(동시성) 정리하면 멀티 쓰레드의 목적은 동시성과 병렬성을 활용해서 여러 작업을 동시에 실행하는 것처럼 보이게하거나 동시에 실행하는 것이다.
Reference
- 자바 완전 정복 | 김동형 지음
댓글