프로세스란?
실행 파일이 실행되어 있는 메모리에 적재된 인스턴스(하나의 클래스에서 생성된 객체)
만약 unity.exe가 실행 파일이라면, 이 실행 파일에 담겨있는 데이터와 코드가 메모리에 적재되어 동작하게 하는 것이 프로세스입니다.
+ 힙과 스택도 구성 요소입니다.
특징으로는
운영체제로부터 독립된 메모리 공간과 자원을 할당받는다는 점과,
프로세스는 하나 이상의 스레드로 구성된다는 점입니다.
이는 하나만 사용하는 단일 스레드의 구조거나 여러 개의 스레드를 사용하는 멀티 스레드의 구조가 있습니다.
스레드(Thread)란?
프로세스 내에서 실행되는 흐름의 단위입니다.
운영체제가 CPU 시간을 직접 할당하는 기본 단위가 바로 스레드입니다.
특징으로
같은 프로세스의 다른 스레드와 코드, 데이터, 힙을 공유합니다.
하지만 스택은 각각 따로 가집니다 (독립적인 실행 흐름을 유지하기 위함이라고 합니다).
단일 스레드 프로세스: 한 개의 실행 흐름만 있습니다.
멀티 스레드 프로세스: 여러 개의 실행 흐름이 동시에 실행됩니다.
그렇다면 멀티 스레드를 이용했을 때의 장단점을 간단히 알아보도록 하겠습니다.
장점이 있나요?
1. 먼저 응답성을 높일 수 있다고 합니다.
예를 들어 단일 스레드를 사용하는 프로그램을 만들었고, 이는 한 작업이 10분이 걸린다고 가정하겠습니다.
그러면 그 10분 동안 작업을 시작했다면 취소하고 싶어도 프로그램은 사용자에게 반응하지 않기 때문에(없기 때문에) 작업을 취소할 수 없는 상황에 놓이게 됩니다.
하지만 멀티 스레드를 사용하는 프로그램을 만들어서, 작업과 플레이어에게 응답하는 스레드를 나누었다면, 작업을 진행하면서도 취소 명령을 받을 수 있습니다.
2. 스레드끼리 자원 공유가 쉽습니다.
같은 프로세스 내에서는 각기 다른 스레드라 하여도, 코드와 데이터, 힙을 공유합니다.
그렇기에 같은 프로세스 내에서는 스레드끼리 자원을 공유하기에 멀티 프로세스 보다 좋은 상황이 생기기도 합니다.
3. 경제적입니다.
프로세스를 띄우기 위해 메모리와 자원 할당하는 작업은 비용이 비쌉니다.
하지만 여러 스레드를 띄우는 작업은 프로세스에 있는 메모리와 자원을 그대로 사용하기에 비용을 지불하지 않게 됩니다.
그럼 멀티 스레드를 사용하는 것은 엄청 좋고 무조건 써야 하고 그렇겠네요?
꼭 그런 것은 아니죠. 단점도 만만치 않습니다.
그럼 단점은?
1. 구현이 복잡합니다.
멀티 스레드 작업은 구현이 복잡한 것이 가장 큰 단점이라고 생각이 듭니다.
동기화, 데드락 등등의 문제들이 발생할 수 있으며,
테스트도 쉽지 않은 것이 디버깅 작업 시, 매번 실행 순서가 달라질 수 있어 어렵다고 합니다.
2. 소프트웨어의 안정성을 악화시킬 수 있습니다.
멀티 프로세스 기반의 소프트웨어는 여러 자식 프로세스 중 하나가 죽어도 그 자식에게만 피해가 갈 뿐 부모나 다른 프로세스에게는 아무 문제가 가지 않습니다.
하지만 멀티 스레드 기반 소프트웨어는 자식 하나에 문제가 생기면 부모고 자식이고 모든 프로세스 전체에 영향을 줍니다.
3. 과용하면 성능이 저하될 수 있습니다.
아까 멀티 스레드의 장점이 응답성, 경제적 등으로 성능이 장점이라 하였으나, 너무 많이 사용하게 되면 오히려 사용자에게 독으로 돌아오게 됩니다. 스레드가 CPU를 사용하기 위해서는 각 스레드의 작업마다 전환을 해야 합니다.
이 전환 Switching 시 많은 비용을 사용하게 됩니다.
즉, 너무 많은 스레드가 너무 많은 작업을 스위칭하게 된다면 프로그램이 실제 일하는 시간보다 스위칭 시간이 더 들게 되어 성능이 저하됩니다.
그렇다면 이제 스레드를 사용해 봅시다.
간단히 구현을 해보겠습니다.
static void DoSomething()
{
for (int i = 0; i < 10; i++)
{
Console.WriteLine($"DoSomething {i}");
}
}
//Main
static void Main(string[] args)
{
Thread t1 = new Thread(new ThreadStart(DoSomething));
t1.Start();
t1.Join();
}
이 코드에서 실질적으로 스레드가 메모리에 적재되는 시점은 어디일까요?
t1을 선언했을 때?
t1.Start 메서드 호출 시?
t1.Join 메서드 호출 시?
바로 t1.Start 메서드를 호출했을 때입니다.
Thread 클래스의 인스턴스인 t1은 그저 준비만 할 뿐입니다.
t1.Start() 메서드가 호출되고 나면, CLR은 스레드를 실제로 생성합니다.
그다음 DoSomething을 실행하죠.
그럼 t1.Join()은 뭔가요?
Join은 스레드를 합류시켜(wait) 실행 흐름을 동기화하는 역할입니다.
DoSomething을 끝낼 때까지 블록 되었다가 DoSomething의 작업이 끝나면 다시 반환되어 다음 코드가 작업되게 합니다.

t1.Start()에서 메인 스레드에서 분리되어 다른 스레드에 할당됩니다.
DoSomething 내부 루프가 수행되는 동안 t1은 독립적으로 동작합니다.
메인 스레드는 t1.Join()에 도달하기 전까지는 자유롭게 다른 일을 할 수 있습니다.
t1.Join()에서 스레드가 완전히 끝날 때까지 대기합니다.
t1.Join() 메서드가 반환되면 프로그램의 흐름은 다시 메인 스레드로 합쳐져 다음 작업을 시작합니다.
이번에는 이렇게 간단히 프로세스, 스레드가 무엇인지, 장단점은 무엇인지 공부해 보았습니다.
다음에는 스레드를 임의로 종료해 보고 스레드에게 무슨 상태가 있는지 공부해 보겠습니다.
'C# > 문법' 카테고리의 다른 글
| C# ObserverPattern (옵저버 패턴) (0) | 2025.10.07 |
|---|---|
| C# 스레드 임의로 종료하기 / 스레드의 상태들 (2) | 2025.08.25 |
| C# object와 박싱, 언박싱 (2) | 2025.08.13 |
| C# 문법 17 -- 데이터 형식 정리 9 (0) | 2024.12.07 |
| C# 문법 16 -- 데이터 형식 정리 8 (0) | 2024.12.06 |