C# 개념정리

프로세스 / 프로세스와 스레드

meltingmelvin 2024. 5. 1. 14:26
프로세스

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

- 운영 체제에 의해 메모리에 로드되어 실행되는 프로그램 코드와 데이터의 집합으로, 독립적인 실행 단위

 

=> 자신만의 독립된 메모리 영역(코드, 데이터, 힙, 스택)과 시스템 자원 할당받는다.

=> 독립적이므로 각각의 프로세스는 각각 실행되며, 하나의 프로세스가 다른 프로세스의 메모리에 직접 접근하는 것은 허용되지 않는다.

=> 프로세스 간의 통신은 IPC(Inter Process Communication) 매커니즘에 의해 이루어진다.

 

 

스레드

- 프로세스 내에서 실행되는 단위

- 프로세스 내의 코드를 실행하는 가장 작은 단위로, 프로세스의 자원을 공유하며 동작한다.

 

=> 각 스레드는 자신의 스택(함수 호출, 지역 변수 등)과 CPU 레지스터 상태를 가진다.

=> 스레드는 자원을 공유하므로 하나의 프로세스 내에서 다수가 병렬로 실행 가능하나, 동기화 문제가 발생할 수 있다.

 

 

 

프로세스와 스레드의 차이점

 

더보기

메모리와 자원의 공유: 

프로세스는 독립된 메모리 공간을 가지지만, 스레드는 같은 프로세스 내에서 메모리와 자원을 공유한다.


생성과 관리의 비용: 

프로세스는 생성 및 관리 비용이 높고, 리소스 사용량이 많다. 반면, 스레드는 가볍고 효율적이다.


통신과 동기화: 

프로세스 간 통신은 복잡하고 비용이 많이 들지만, 스레드 간 통신은 상대적으로 간단하다. 

다만, 스레드는 동기화 문제를 주의해야 한다.


독립성과 안정성: 

프로세스는 강력한 격리성으로 인해 안정적이지만, 

스레드는 자원 공유로 인해 하나의 스레드에 문제가 생기면 전체 프로세스에 영향을 줄 수 있다.

 

 


이러한 특징 때문에,  리소스가 많이 필요한 독립적인 작업 프로세스로 실행하는 것이 좋고,

리소스를 공유하며 빠른 응답이 필요한 작업은 스레드를 사용하는 것이 효과적이다.

( => 스레드는 비용이 있지만 운영체제의 응답성이 좋아지게 하는 효과가 있다.)

 

더보기

모든 스레드는 다음의 비용을 하나씩은 가진다.

 

  1. 스레드 커널 객체 : OS는 개별 스레드별로 고유의 데이터 구조체를 할당화하고 초기화한다. 이 안에 흔히 말하는 '컨텍스트'라는 정보도 포함되어 있다. 컨텍스트는 CPU 내의 레지스터들의 값을 저장하고 있는 메모리 블록이다.(64비트 기준 1240바이트)
  2. 스레드 환경 블록(TEB) : 스레드의 컨텍스트 정보. 유저 모드(모든 응용프로그램이 빠르게 접근할 수 있는 주소공간)에 할당되고 초기화된다. TIB(Thread information block)라고도 하는 듯.
  3. 유저 모드 스택 : 지역 변수와 함수의 매개변수를 저장. 함수가 반환될 때 다음으로 수행해야 할 위치 기억. (대략 1MB)

  4. 커널 모드 스택 : 커널 모드 함수로 매개변수를 전달해야 할 때 사용 (대략 12~24KB)

  5.  DLL의 스레드 attach/detach 통지 : 스레드가 생성/종료 될 때 모든 비관리 DLL들에게 스래드 생성/종료를 알린다. 일부 프로세스의 경우 수백개의 DLL을 사용하기도 하기 때문에 비용이 제법 클 수 있다.

 

여기에 더해 자신의 퀀텀만큼 일을 한 스레드가 교체 될 때 컨텍스트 전환이라는 비용이 발생한다. 과정은 다음과 같다.


1. 현재 수행 중인 스레드의 CPU 레지스터를 스레드의 컨텍스트 구조체에 저장하고,
2. 가상 메모리 주소를 전환하고,
3. 새로 작업을 수행할 스레드의 컨텍스트 구조체 값들을 CPU 레지스터로 로드함.

 

이런 컨텍스트 전환은 엄청난 비용을 초래할 수 있다.

=> 만약 CPU가 컨텍스트 전환 없이 계속 이전 스레드를 수행한다면 CPU 캐시를 많이 활용할 수 있지만, 컨텍스트가 전환되면 CPU 캐시의 내용이 쓸모 없어지기 때문이다.

 

더 나아가 가비지 수집을 진행할 때 CLR은 모든 스레드를 일시 정지 시킨다. 

 

이처럼 스레드는 가능한 만들지 않는 것이 좋다.

그럼에도 응답성이 좋은 운영체제를 만들기 위해 스레드를 선택하게 되는 것이다.

 

+) 만약 CPU가 여러개라면?

=> 각각의 CPU 코어가 개별적으로 컨텍스트 전환을 수행하므로 스레드를 더 효율적으로 쓸 수 있다. 물론 스레드의 개수가 컴퓨터의 CPU수와 일치한다면 최적일 것이다.

 

참고 : 제프리 리처, CLR via C# 4판 , 비제이퍼블릭, 26장. 스레드의 기본 [777~801p]

 

 

 

참고자료

 

https://ksw0723.tistory.com/127

https://tsyang.tistory.com/103