[멀티스레딩] 1.2 스레드

연두비두밥·2024년 4월 25일
post-thumbnail

스레드란?

  • 프로세스 내에서 실행되는 작업 단위를 의미한다.
  • 일반적으로 OS는 대부분 스레드(Thread)라는 기능을 제공한다.

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

  • 스레드는 한 프로세스 안에 여러 개가 존재
  • 한 프로세스 안에 있는 스레드는 프로세스 안에 있는 메모리 공간을 같이 사용할 수 있다.
  • 스레드마다 스택을 가진다. 이는 각 스레드에서 실행되는 함수의 로컬 변수들이 스레드마다 있다는 것을 의미

즉, "프로그램을 실행하면 프로세스가 생성되고, 프로세스 안에는 유일한 스레드가 있고 그안에서 프로그램이 실행된다"

여기서 '유일한 스레드' 는 싱글스레드 프로그램이라고 한다.
싱글 스레드로만 작동하도록 프로그램을 설계하고 구현하는 것을 싱글스레드 모델(single threaded model)이라고 한다.
그럼 반대로 '여러개의 스레드'는 멀티스레드 프로그램이다. 또한 멀티 스레드로 작성된 프로그램은 멀티스레드 모델(multi threaded model)이라고 한다.

그림과 같이 프로세스 안에서 여러 스레드를 생성시킬 수 있다. 이렇게 만들어진 스레드는 동시에 한꺼번에 실행된다.

멀티스레드

  • 여러 스레드가 동시에 여러 가지 일을 처리하게 하는 것

스레드의 메모리 영역

  • 스레드는 프로세스의 힙 영역을 공유하고 스레드 각자만의 호출스택을 가진다.
    그 이유는 스레드마다 다른 흐름(함수호출)을 가지는데, 함수가 호출되고 나면 호출자(caller) 함수를 실행했던 지점으로 되돌아가야한다. 그렇기 때문에 호출 스택(call stack)을 가질 수 밖에 없다.
    추가적으로 각 호출 스택 안에 함수 안에 선언된 지역 변수(또는 로컬 변수)도 같이 들어있다.
    그렇기 때문에 각 스레드는 각자 호출 스택을 가진다.

스레드 생성

  • 스레드는 운영체제나 런타임 라이브러리에서 제공되는 스레드 생성용 함수를 호출해서 생성한다.
    이때, 함수 인자로 스레드가 최초로 실행할 함수와 그 함수가 받아들일 매개변수를 넣어주어야 한다.
// __[예제 1]__
void main()
{
	// 1. Start Thread
	t1 = CreateThread(TreadProc, 123);
	// 2. 할 일
    ....
	// 3. Thread가 종료될 떄까지 대시
	t1.Join();
}
ThreadProc(int)
{
	// 4. 일 처리
}

위 예제를 살펴보면, CreateThread는 새로운 스레드 1을 생성한다. 이 코드에서는 ThreadProc라는 실행할 함수와 인자로 123을 받았다.
여기서 생성된 스레드 1과 메인 스레드의 진행흐름이 달라진다.
먼저 메인 스레드는 2로 넘어가게 될 것이다.(실행지점 2)
스레드 1은 ThreadProc 함수를 호출 할 것이다.(실행지점 5)
이제부터 프로세스 안에서는 메인 스레드와 스레드 1이 공존한다.

여기서 주의해야 할 점

  • 메인 스레드가 먼저 실행될지, 스레드가 실행될지는 아무도 모른다. 즉, 실행지점 2가 먼저 실행될지 실행지점 5가 먼저 실행될지는 모른다는 것이다. 디버깅을 여러 차례 실행하면 무작위로 실행된다.
    이론적으로 어느 것이 먼저 실행되는지 규정된 바는 없다.
추가적 예제 설명
  • 프로그램은 동시에 여러 일을 하고 있는데, 어느 것이 실행이 먼저 끝날지는 아무도 모른다.
  • 메인 스레드의 일이 먼저 끝났다면, 메인 스레드는 3번을 실행하게 된다. 3의 Join() 함수가 하는 일은 "스레드 1의 일이 모두 끝날 때까지 기다려라"이다. 스레드 1은 아직 4에 머물러 있고, 3에서는 Join()을 실행하고 있는 메인 스레드는 여기서 실행을 일시 정지하고 기다린다.
    즉, Join을 만나게 되고 스레드 1의 실행이 종료될때까지 대기한다.
    이를 "메인 스레드가 대기중"이라고 표현한다.
    5가 끝나고 더 이상 할 일이 없는 스레드는 소멸한다.
  • 스레드보다 메인 스레드가 먼저 종료되면, 메인 스레드가 종료되었지만 다른 스레드가 일을 하고 있기 때문에 프로세스는 종료되지 않는다. 즉, 프로그램이 종료되지 않는다. 이를 좀비 프로세스라고 한다.

참고

모던 C++에서는

std::trhead t1(TreadProc,123);

과 같이 스레드 생성이 통일되었다.

profile
꾸준하고 싶은 사람

0개의 댓글