📚 Study
[Operating System] 프로세스와 스레드
목차
들어가기에 앞서동시성 Concurrency병렬성 Parallelism프로세스와 스레드✨프로세스 Process단일 프로세스 시스템멀티 프로그래밍멀티 태스킹✨스레드 Thread프로세스와 스레드의 메모리구조프로세스의 메모리 구조각 프로세스는 독립된 메모리 공간을 가짐스레드의 경우, 프로세스의 자원을 공유하며 독립된 스택 영역을 가짐프로세스간 자원 공유 방법은 없을까?멀티프로세스와 멀티스레드멀티프로세서와 멀티코어예제요약질문출처
들어가기에 앞서
동시성 Concurrency
- 한 순간에 여러 가지 일이 일어나는 것이 아님
- 짧은 전환으로 여러 가지 일을 동시에 처리하는 것처럼 보이는 것
병렬성 Parallelism
- 실제로 동시에 작동되는 것
프로세스와 스레드
✨프로세스 Process
- 프로그램 = 컴퓨터가 실행할 수 있는 명령어들의 집합
- 프로세스 = 컴퓨터에서 실행 중인 프로그램의 인스턴스, 각각의 프로세스는 독립된 메모리 공간을 할당 받음
- CPU = 명령어를 실행하는 연산장치
- 메인 메모리 = 프로세스가 CPU에서 실행되기 위해 대기하는 곳
프로그램 | 프로세스 |
어떤 작업을 하기 위해 실행할 수 있는 파일 | 실행되어 작업중인 컴퓨터 프로그램 |
파일이 저장 장치에 있지만 메모리에는 올라가 있지 않은 정적인 상태 | 메모리에 적재되고 CPU 자원을 할당받아 프로그램이 실행되고 있는 상태 |
쉽게 말해 그냥 코드 덩어리 | 그 코드 덩어리를 실행한 것 |
단일 프로세스 시스템
- 한 번에 하나의 프로그램만 실행됨
- 단점 = CPU 사용률이 좋지 않음(IO 작업 중에는 CPU가 쉬는 시간이 생김)
멀티 프로그래밍
- 여러 개의 프로그램을 메모리에 올려두고 동시에 실행시키자
- IO작업이 발생하면 다른 프로세스가 CPU에 의해 실행됨
- CPU 사용률 극대화가 목적
- 단점 = CPU 사용 시간이 길어지면 다른 프로세스는 계속 대기
멀티 태스킹
- 프로세스가 한 번 CPU를 사용할 때는 아주 짧은 시간(=quantom)만 사용하도록 하자
- 멀티프로그래밍 + CPU 시간을 아주 짧게
- 프로세스의 응답 시간을 최소화 시키는 것이 목적 ⇒ 유저가 느끼기에 여러 프로그램이 동시에 실행된다는 느낌을 주게 됨
- 한계
- 여러 프로세스 동시 실행 OK, 하지만 하나의 프로세스가 동시에 여러 작업을 수행하지는 못함
- 프로세스의 컨텍스트 스위칭은 무거운 작업
- 프로세스간 데이터 공유가 까다로움
그래서 등장한 것이…
✨스레드 Thread
- CPU에서 실행되는 단위(unit of execution)
- 프로세스는 한 개 이상의 스레드를 가질 수 있다
- 같은 프로세스 내부의 스레드끼리의 컨텍스트 스위칭은 가볍다!!
- 스레드는 자신들이 속한 프로세스 메모리 영역을 공유함(코드 데이터 힙 영역 공유, 스택 제외)
- ⇒ 장점
- 캐싱 적중률 올라감, 컨텍스트 스위칭 가벼움, 스레드간 데이터 공유가 쉬움
프로세스와 스레드의 메모리구조
프로세스의 메모리 구조
- 코드 영역(Code, Text) - 코드가 기계어 형태로 저장되어 있음
- 데이터 영역(Data) - 코드가 실행되면서 사용하는 전역 변수 등의 데이터
- 힙 영역(Heap) - 생성자, 인스턴스와 같이 동적으로 할당되는 데이터
- 스택 영역(Stack) - 지역 변수, 호출한 함수가 종료되면 되돌아올 임시 자료 등을 저장하는 독립적인 공간, 함수의 호출과 함께 할당되며, 함수 호출이 완료되면 소멸
각 프로세스는 독립된 메모리 공간을 가짐
스레드의 경우, 프로세스의 자원을 공유하며 독립된 스택 영역을 가짐
프로세스간 자원 공유 방법은 없을까?
- IPC(Inter-Process Communication) 사용
- LPC(Local inter-Process Communication) 사용
- 별도로 공유 메모리를 만들어서 정보를 주고받도록 설정
멀티프로세스와 멀티스레드
- 멀티 스레드
- 하나의 프로세스가 동시에 여러 작업을 실행
- 확장된 멀티 태스킹 개념 = 여러 스레드가 아주 짧게 쪼개진 cpu time을 나눠 갖는 것
- 멀티 프로세스
- 두 개 이상의 프로세서나 코어를 활용하는 시스템
- 처리 방식의 일종, 한 어플리케이션에 대한 처리방식
- 멀티프로세스 ≠ 여러 개의 어플리케이션을 띄워놓은 것
- 각 프로세스가 독립적인 영역 가짐, IPC 통한 통신, 자원 소모적, 개별 메모리 차지, 컨스 비용 큼, 동기화 필요 X
- 멀티스레드
- 스레드간 긴밀한 연결, 공유자원으로 통신 비용 절감, 공유 자원으로 메모리 효율적, 컨스 비용 적은, 공유 자원 관리 필요
- 멀스가 더 좋아보이는데 멀티프로세스를 이용하는 이유?
- 하나의 스레드가 에러나면 다 죽어!
- 좀더 하드웨어 측면에 가까움
- 동시성과 병렬성
멀티프로세서와 멀티코어
- 코어
- CPU 내부의 일꾼, 각종 연산을 하는 핵심요소
- 싱글코어, 듀얼코어, … 코어가 많아질수록 일반적으로 처리속도가 빨라짐
- 프로세서
- 오늘날 CPU를 대체하는 용어
멀티 코어 | 멀티 프로세서 |
프로그램 명령을 읽고 실행할 수 있는 코어라고 하는 두 개 이상의 독립적인 처리 장치를 갖춘 단일 CPU 또는 프로세서 | 프로그램을 동시에 처리할 수 있는 두 개 이상의 CPU가 있는 시스템 |
단일 프로그램을 더 빠르게 실행 | 여러 프로그램을 더 빠르게 실행 |
멀티프로세서만큼 안정적이지 않음 | 한 CPU에 장애가 발생해도 다른 CPU에는 영향을 미치지 않으므로 더욱 안정적 |
트래픽이 적음 | 트래픽이 더 많음 |
구성할 필요가 없음 | 복잡한 구성이 거의 필요하지 않음 |
매우 저렴(다중 CPU 지원 시스템이 필요하지 않은 단일 CPU). | 멀티코어에 비해 비용이 많이 듦(여러 프로세서를 지원하는 시스템이 필요한 여러 개의 개별 CPU가 필요함). |
- 멀티코어와 멀티프로세서의 유일한 공통점은 처리 속도를 높이는 것
- 멀티코어 시스템의 비용은 멀티프로세서 시스템에서 더 많은 물리적 프로세서를 사용하기 때문에 멀티프로세서 시스템 비용에 비해 저렴
- 처리 속도 (큰 쪽이 빠름)단일 프로그램을 실행 -> 멀티코어 시스템 > 멀티프로세서 시스템여러 프로그램을 실행 -> 멀티프로세서 시스템 > 멀티코어 시스템
- 최신 컴퓨터에는 각각 여러 개의 코어를 가진 여러 개의 CPU 존재
예제
아래 상황에 대하여 멀티태스킹 / 멀티스레딩 / 멀티프로세싱 OX 생각해보기
싱글코어 CPU에 싱글 스레드 프로세스 두개
- 멀티태스킹 O
- 멀티스레딩 X
- 멀티프로세싱 X
싱글코어 CPU에 듀얼 스레드 프로세스 한개
- 멀티태스킹 O
- 멀티스레딩 O
- 멀티프로세싱 X
듀얼코어 CPU에 싱글 스레드 프로세스 두개
- 멀티태스킹 X
- 멀티스레딩 X
- 멀티프로세싱 O
듀얼코어 CPU에 듀얼 스레드 프로세스 한개
- 멀티태스킹 X
- 멀티스레딩 O
- 멀티프로세싱 O
듀얼코어 CPU에 듀얼 스레드 프로세스 두개
- 멀티태스킹 O
- 멀티스레딩 O
- 멀티프로세싱 O
요약
- 프로세스는 프로그램이 실행된 것이다
- 스레드는 한 프로세스 내에서 나뉘어진 하나 이상의 실행 단위이다
- 한 어플리케이션에 대한 작업을 동시에 하기 위해서 2가지 처리 방식(멀티 프로세스, 멀티 스레드)이 있다
- 동시에 실행되는 것처럼 보이기 위하여 실행단위는 시분할로 cpu를 점유하며 컨텍스트 스위칭 한다
- 멀티 프로세스는 독립적인 메모리를 가지고 있지만, 멀티 스레드는 자원을 공유한다. 각각의 장단점이 있다
질문
프로세스와 스레드에 대해 설명해보세요.
- 프로세스란 실행중인 프로그램 인스턴스이고, 스레드란 프로세스 안에서 실행되는 작업 단위입니다.
- 프로세스는 메모리와 CPU를 할당받아 사용하는데 스레드는 프로세스 안에서 다른 스레드와 메모리와 CPU를 공유하고 고유한 stack 메모리만을 각자 할당받습니다.
동시성과 병렬성에 대해 설명해보세요.
- 동시성은 여러 작업이 같은 시간대에 실행되는 것처럼 보이게 하는 것이고, 병렬성은 여러 작업이 실제로 동시에 실행되는 것입니다.
스레드간 컨텍스트 스위칭은 항상 가벼울까요?
- 같은 프로세스의 스레드 간 컨텍스트 스위칭은 프로세스 컨텍스트 스위칭보다 가볍지만, 다른 프로세스의 스레드간 컨텍스트 스위칭은 사실상 프로세스 컨텍스트 스위칭과 같으므로 가볍지 않습니다.
멀티스레드가 멀티프로세스보다 항상 좋을까요? 둘 중 하나를 선택해야 한다면 어떤 기준으로 판단해야 할지?
- 멀티 스레드는 멀티 프로세스보다 적은 메모리 공간을 차지하고 컨텍스트 스위칭이 빠르다는 장점이 있지만, 오류로 인해 하나의 스레드가 종료되면 전체 스레드가 종료될 수 있다는 점과 동기화 문제, 데이터 경합 문제를 가지고 있습니다.
- 반면, 멀티 프로세싱 방식은 하나의 프로세스가 죽더라도 다른 프로세스에는 영향을 끼치지 않고 정상적으로 수행된다는 장점이 있지만, 멀티 스레드보다 많은 메모리 공간과 CPU 시간을 차지한다는 단점이 존재합니다.
- 이 두 가지는 동시에 여러 작업을 수행한다는 점에서 같지만 적용해야 하는 시스템에 따라 적합/부적합이 구분되므로 대상 시스템의 특징에 따라 적합한 동작 방식을 선택하고 적용해야 합니다.
- 만약 작업의 안전성을 보장하고 싶다면 멀티프로세싱을, 안전성보다는 성능과 응답시간을 보장하고 싶다면 멀티스레딩을 선택하는 것이 좋을 것 같습니다.
스레드를 많이 쓸수록 성능이 좋아질까요?
- 스레드를 많이 사용하는 것이 항상 성능 향상으로 이어지지는 않으며, 오히려 오버헤드나 경쟁 상태가 발생해 성능이 저하될 수 있습니다.
Stack 메모리를 스레드마다 독립적으로 할당하는 이유는?
- 각 스레드가 독립적인 함수 호출과 로컬 변수를 가질 수 있도록 하기 위해 스택 메모리를 독립적으로 할당합니다.
- 즉, 스레드의 정의에 따라 독립적인 실행 흐름을 추가하기 위한 최소 조건으로 독립된 스택을 할당합니다.
PC 레지스터를 스레드마다 독립적으로 할당하는 이유는?
- PC 레지스터 값은 스레드가 명령어의 어디까지 수행했는지를 나타냅니다. 스레드는 CPU를 할당받았다가 스케줄러에 의해 다시 선점당하기 때문에 명령어가 연속적으로 수행되지 못하고 어느 부분까지 수행했는지 기억할 필요가 있습니다. 따라서 PC 레지스터를 각 스레드에 독립적으로 할당합니다.
“리눅스에서는 프로세스와 스레드가 같다” 의 의미?
- 리눅스 커널에서는 프로세스와 스레드를 동일하게 봅니다
- 리눅스는 1:1 모델
- ⇒ 어차피 각각의 프로세스가 하나의 스레드다, 혹은 스레드도 사실상 경량 프로세스이다
- ⇒ 프로세스와 스레드가 같은 주소 공간을 공유하는 프로세스로 취급됨
- PID, TID(스레드 아이디)
사용자 수준의 스레드와 커널 수준의 스레드의 차이는 무엇인가요?
- 관리 주체:
- 사용자 수준 스레드: 사용자(프로그램) 공간에서 관리되며, 커널은 이를 인식하지 못함.
- 커널 수준 스레드: 운영 체제의 커널이 스레드를 직접 관리하고 스케줄링함.
- 장점:
- 사용자 수준 스레드: 컨텍스트 스위칭이 빠르고, 플랫폼 독립적.
- 커널 수준 스레드: 진정한 병렬 처리 가능, 효율적인 자원 관리.
- 단점:
- 사용자 수준 스레드: 블로킹 문제 발생 가능, 병렬 처리 불가능.
- 커널 수준 스레드: 컨텍스트 스위칭이 느리고, 커널 오버헤드 증가.
스프링 프레임워크는 멀티스레딩과 멀티프로세싱 중 어떤 걸 사용하나요?
- 스프링은 주로 멀티스레딩을 사용하여 동시성을 처리합니다.
- 서블릿 컨테이너: 스프링 애플리케이션은 보통 서블릿 컨테이너(Tomcat, Jetty 등) 위에서 실행됩니다. 서블릿 컨테이너는 각 HTTP 요청을 별도의 스레드에서 처리합니다. 이 방식으로 동시에 여러 요청을 처리할 수 있습니다.
- @Async 어노테이션: 스프링은 @Async 어노테이션을 사용하여 비동기적으로 실행될 메서드를 지정할 수 있습니다. 이 경우 스프링은 스레드 풀(Thread Pool)에서 스레드를 할당하여 비동기 작업을 수행합니다.
- 스레드 풀(Thread Pool): 스프링에서는 TaskExecutor를 사용해 스레드 풀을 관리할 수 있습니다. 스레드 풀은 미리 일정 수의 스레드를 생성해 두고, 작업이 요청될 때마다 스레드를 재사용함으로써 스레드 생성과 소멸의 오버헤드를 줄여줍니다.
- 스프링 스케줄러: 스프링은 @Scheduled 어노테이션을 사용하여 주기적으로 실행될 작업을 정의할 수 있습니다. 이 경우에도 스레드 풀이 사용되어 멀티스레딩 방식으로 스케줄링 작업이 실행됩니다.
- 고려사항: 스레드 간의 자원 공유로 인해 동기화 문제가 발생할 수 있습니다. 따라서, 스레드 안전(Thread-safety)을 유지하기 위한 고려가 필요하며, 잘못된 동기화는 데드락(Deadlock)이나 경쟁 조건(Race Condition)을 초래할 수 있습니다.