본문 바로가기
인프런/김영한의 실전 자바 - 고급 1편, 멀티스레드와 동시성

[인프런] 김영한의 실전 자바 - 고급 1편, 멀티스레드와 동시성 / 1. 멀티태스킹과 멀티프로세싱

by hxxyeoniii 2025. 1. 6.

멀티태스킹

프로그램A의 코드와 프로그램B 코드를 번갈아 수행

현대 CPU는 초당 수십억 번 이상의 연산을 수행

-> CPU가 매우 빠르게 두 프로그램 코드를 번갈아 수행한다면, 사람은 두 프로그램이 동시에 실행되는 것처럼 느낌

-> 각 프로그램의 실행 시간을 분할해 마치 동시에 실행되는 것 처럼 하는 기법 = 시분할(Time Sharing)

-> 하나의 컴퓨터 시스템(CPU 코어 하나)이 동시에 여러 작업을 수행하는 능력 = 멀티태스킹

 

* CPU에 어떤 프로그램이 얼만큼 실행될지는 OS가 결정 = 스케줄링

 

 

 

멀티프로세싱

 

CPU 코어가 둘 이상일 경우

-> 둘 이상의 프로세서(CPU 코어)를 사용해 여러 작업을 동시에 처리하는 기술 = 멀티프로세싱

 

 

 

멀티태스킹 vs 멀티프로세싱

멀티태스킹은 OS 소프트웨어 관점, 멀티프로세싱은 하드웨어 장비 관점

 

멀티태스킹

- 단일 CPU가 여러 작업을 동시에 수행하는 것처럼 보이게 하는 것

- SW 기반으로 CPU 시간을 분할해 각 작업에 할당

 

멀티프로세싱

- 여러 CPU를 사용해 동시에 여러 작업 수행

- HW 기반으로 성능 향상

 


프로세스와 스레드

 

프로세스

1. 프로그램은 실제 실행 전 단순 파일에 불과

2. 프로그램을 실행하면 프로세스가 만들어지고 프로그램이 실행됨

3. OS 안에서 실행중인 프로그램 = 프로세스

4. 프로세스는 실행 중인 프로그램의 인스턴스

5. 자바 언어로 비유하면 클래스는 프로그램, 인스턴스는 프로세스

 

-> 각 프로세스는 독립적 메모리 공간을 가지고 있으며 OS에서 별도의 작업 단위로 분리해 관리됨

-> 각 프로세스는 서로 간섭하지 않음 = 서로의 메모리에 직접 접근 불가

-> 이렇게 격리되어 관리되기에 프로세스가 충돌해도 다른 프로세스에 영향을 미치지 않음

 

 

 

프로세스의 메모리 구성

1. 코드 섹션 : 실행할 프로그램의 코드가 저장되는 부분

2. 데이터 섹션 : 전역 변수 및 정적 변수가 저장되는 부분(그림에서 기타)

3. : 동적으로 할당되는 메모리 영역

4. 스택 : 메서드 호출 시 생성되는 지역 변수와 반환 주소가 저장되는 영역(스레드에 포함)

 

 

 

스레드

1. 프로세스는 하나 이상의 스레드를 반드시 포함

2. 프로세스 내에서 실행되는 작업의 단위

3. 한 프로세스 내 여러 스레드가 존재할 수 있으며, 프로세스가 제공하는 동일 메모리 공간을 공유

4. 프로세스보다 단순해 생성, 관리가 단순하고 가벼움

 

 

 

스레드의 메모리 구성

1. 공유 메모리 : 같은 프로세스의 코드 섹션, 데이터 섹션, 힙은 프로세스 안의 모든 스레드가 공유함

2. 개별 스택 : 각 스레드는 자신의 스택을 갖고 있음

 

 

 

프로그램이 실행된다는 것은 무슨 의미일까?

프로그램 실행 시 OS는 먼저 디스크에 있는 파일 덩어리인 프로그램을 메모리로 불러오며 프로세스를 만든다.

프로그램이 실행된다는 것은 프로세스 안의 코드가 한 줄씩 실행된다는 것이다.

그리고 스레드가 실처럼 코드를 위에서 아래로 하나씩 꿰며 내려가는 것이다. 

-> 프로세스의 코드를 실행하는 흐름을 스레드라 한다.

-> 프로세스는 실행 환경과 자원을 제공하는 컨테이너 역할 & 스레드는 CPU를 사용해 코드를 하나하나 실행

 

 

멀티스레드?

하나의 프로세스 안에는 최소 하나의 스레드가 존재한다.

그리고 하나의 프로그램도 그 안에서 동시에 여러 작업이 필요하다.

 

예시 : 워드로 문서를 편집하며 문서가 자동 저장되고 맞춤법 검사도 수행한다. + 유튜브는 영상을 보며 댓글을 달 수 있다.

 

<워드 프로그램 - 프로세스 A>

1) 스레드1 : 문서 편집

2) 스레드2 : 자동 저장

3) 스레드3 : 맞춤법 검사

 

<유튜브 - 프로세스 B>

1) 스레드1 : 영상 재생

2) 스레드2 : 댓글


컨텍스트 스위칭

OS의 멀티태스킹을 생각해보자.

- CPU는 1개, 스레드A와 스레드B가 존재

 

OS가 스레드A를 실행한다. 멀티태스킹을 위해 스레드A를 멈추고 스레드B를 실행한다.

이후 스레드A로 돌아가려고 할 때, 스레드A의 코드가 어디까지 수행되었는지 위치를 찾고 계산하던 변수들의 값을 CPU에서 다시 불러드려야 한다.

-> 스레드A를 멈추는 시점에 CPU에서 사용하던 값들을 메모리에 저장해두어야 하고 다시 실행하는 시점에 CPU에서 이 값들을 불러와야 한다.

-> 이를 컨텍스트 스위칭이라 한다.

-> 멀티스레드는 대부분 효율적이지만 컨텍스트 스위칭이 필요해 항상 효율적이지만은 않다.

 

CPU 코어가 2개

: 스레드 1, 스레드 2로 나눠 멀티스레드로 병렬처리할 수 있다. 

: 모든 CPU를 사용하므로 연산이 2배 빨라진다.

 

CPU 코어가 1개

: 스레드가 2개라면 중간중간 컨텍스트 스위칭 비용이 발생한다.

 

 

실무에서는...

1) CPU 4개 + 스레드 2개

: 스레드 숫자가 적어 모든 CPU를 활용할 수 없지만 컨텍스트 스위칭 비용이 줄어듬

 

2) CPU 4개 + 스레드 100개

: 스레드 숫자가 너무 많아 CPU를 100% 활용할 수 있지만 컨텍스트 스위칭 비용이 늘어남

 

3) CPU 4개 + 스레드 4개

: 이상적?

 

 

* CPU 바운드 작업 vs I/O 바운드 작업

CPU 바운드 작업

1. CPU 연산 능력을 많이 요구하는 작업

2. 주로 계산, 데이터 처리, 알고리즘 실행 등 CPU의 처리 속도가 작업 완료 시간을 결정하는 경우

3. ex) 복잡한 수학 연산, 데이터 분석, 비디오 인코딩 등

 

I/O 바운드 작업

1. 디스크, 네트워크, 파일 시스템 등과 같은 입출력 작업을 요구하는 작업

2. I/O 작업이 완료될 때까지 대기 시간이 발생해 CPU가 대기 상태에 있는 경우가 많음 -> 스레드가 CPU를 사용하지 않고 I/O 작업이 완료될 때까지 대기

3. ex) DB 쿼리 처리, 파일 읽기쓰기, 네트워크 통신, 사용자 입력 처리 등

 

 

웹 애플리케이션 서버

백엔드 개발자의 경우 주로 웹 애플리케이션 서버를 개발하는데 이는 대부분 사용자의 입력을 기다리거나 DB를 호출하고 결과를 기다리는 등 I/O 바운드 작업이 더 많이 필요하다.

일반적으로 자바 웹 애플리케이션 서버의 경우 사용자 요청 하나에 스레드 1개가 필요하다.

사용자 요청 처리 시 스레드는 CPU의 1%를 사용하고 대부분 데이터베이스 서버의 결과 조회를 기다린다고 가정하자.

CPU 코어가 4개가 있고 사용자 4명이 동시에 요청한다고 하면 각 CPU는 1%씩 총 4%만 사용해 CPU가 놀고 있는 사태가 벌어진다.

따라서 스레드의 숫자는 CPU-바운드 작업이 많은지 I/O 바운드 작업이 많은지에 따라 설정해야 한다.