본문 바로가기

C#

[C#] Thread(스레드)

▣ 프로세스(Process)

: 하나의 프로그램은 하나의 프로세스에 해당한다.


▣ 멀티 태스킹(Multi-Tasking)

-. 프로세스의 경우 운영체제에서 자동으로 관리해준다.

-. 운영체제 차원의 프로세스 관리를 멀티 태스킹이라고 한다.


▣ 프로세스와 스레드

-. 하나의 프로세스 내애세 여러 개의 스레드가 존재할 수 있다.


▣ 스레드란?

-. 하나의 프로그램 내에서 실행되는 함수

-. 한순간에 두 개의 함수가 동시에 실행되면 두 개의 스레드가 동작하는 것이다.


▣ 스레드 프로그램을 할 때 주의해야 할 사항

-. 우선권(Priority)

-. 동기화(synchonization)


윈도우의 장점 중에서 가장 두드러진 것이 바로 멀티 태스킹이다. 윈도우즈에서 작업을 할 때 워드창, 웹 브라우저, 음악 플레이어 정도는 동시에 켜둔 상태에서 작업을 한다. 동시에 이러한 작업이 가능한 것은 운영체제가 CPU의 시간을 분할해서 각각의 프로그램에게 제어권을 한번씩 나누어 주기 때문이다.


이러한 작업의 대상인 프로그램은 하나의 프로세스 형태로 운영체제에서 관리된다. 운영체제 차원의 이런한 프로세스 관리법을 멀티 태스킹이라고 하며, 80386 계열에서는 CPU 차원에서 지원해주기 때문에 더욱 효율적으로 멀티 태스킹이 동작한다.


우리가 목표로 하는 것은 프로그램 단위의 멀티 태스킹이 아니라 하나의 프로그램 내에서 실행되는 멀티 함수이다. 즉 하나의 프로세스 내에 여러 개의 함수를 동시에 실행하고자 하는 것이다.


스레드란 바로 하나의 프로세스 내에서 실행되는 함수를 의미한다. 일반적인 프로세스의 경우 한순간에 하나의 함수만 실행되지만, 스레드를 이용하면 여러 개의 함수를 동시에 실행시킬 수 있다.


동시에 두 개 또는 여러 개의 함수가 실행되기 때문에 어느 함수에게 작업할 권한을 많이 줄것인지에 대해서 생각해보아야 한다. 즉 우선권을 어떤 함수에게 많이 줄 것인지에 관한 것이다.


우선권보다도 더 중요한 것이 바로 공유 자원의 문제이다. 두 개의 함수가 동시에 작업을 진행할 때 둘 다 하나의 자원을 상대로 작업을 하면 미세한 문제가 발생한다.

하나의 자원을 상대로 순서대로 작업이 처리되는 것을 보장하는 기법을 동기화(Synchronization)라고 한다.


▣ 동기화의 보장

-. 공유자원을 상대로 순서대로 작업이 이루어지는 것을 "동기화가 보장된다"라고 말한다.


▣ 스레드의 상태

스레드의 상태를 아는 것은 스레드를 어떻게 제어하느냐와 관련이 있다. 스레드의 상태는 대표적으로 생성 직후의 상태(Unstarted), 실행 가능한 상태(Runnable), 대기상태(Suspended), 실행을 끝내고 죽는 상태(Stopped)로 나눌 수 있다.


일단 스레드가 생성된 후 Start를 하면, 스레드는 3가지 상태로 전이가 가능하다.


□ Unstarted

-. 스레드에 해당하는 함수를 디자인하고, 이 함수의 대리자인 ThreadStart델리게이트를 생성한다. 그리고 생성된 ThreadStart 델리게이트를 매개변수로 하여 Thread를 생성하게 된다. Unstarted 상태는 스레드가 생성된 직후를 의미한다. 이것은 Start하기 바로 직전의 상태를 나타낸다. 이 상태에서 스레드의 Start()함수가 호출되면 실행가능 상태가 되고, 해당 스레드의 함수가 종료하면 바로 Stopped 상태가 된다.


□ 실행가능(Runnable)

-. 새로운 스레드가 생성되어 그 스레드의 Start()함수를 호출하면, 스레드는 Runnable 상태가 된다. Runnable 상태는 CPU를 점유하느냐 하지 못하느냐에 따라 두가지로 나뉘게 된다. CPU를 차지한 스레드가 있을 것이고, 그 나머지는 후보 스레드가 될 것이다.Runnable 상태의 스레드들을 실행큐라고 하는 저장공간에 넣어두고 CLR에 의해서 관리된다. 실행큐란 실행가능 상태에 있는 스레드들을 넣어두는 자료구조이다. 알고 보면 CPU는 한순간에 단 하나의 스레드만을 실행할 수 있다. 실행큐에 있는 스레드들 중에서 하나만을 골라서 실행하는데 번갈아 가면서 실행하는 것이다. 물론 단 하나의 스레드만이 실행 스레드이며 나머지는 후보 스레드가 된다. 이 두가지의 경우를 모두 Runnable 상태라고 한다.


□ 대기상태(Suspended)

-. 현재 실행 중인 스레드에서 Suspend()와 Sleep() 함수를 호출하게 되면 스레드는 Runnable상태에서 Suspended 상태로 전환하게 된다. Runnable 상태를 벗어나는 것이다. 조금 전에 말한 실행큐에서 제거되고 대기큐라는 곳으로 자리를 옮기게 된다. 그리고는 실행큐에 들어갈 조건이 될 때까지 기다리게 된다. 대기큐에 존재하는 스레드들은 CPU를 사용할 권한이 없기 때문에 대기상태가 된다.


-. 이렇게 Suspended()나 Sleep() 함수가 호출될 경우 스레드는 실행가능 상태에서 대기상태로 전환하게 되는데, 반대로 대기 상태에서 실행가능 상태로 전환해주기 위해서는 Suspended() 함수가 호출된 경우에는 Resume()함수를 호출하고, Sleep() 함수가 호출된 경우에는 주어진 시간이 경과하면 자동으로 실행가능(Runnable) 상태가 된다.


□ 종료(Stopped)

-. 스레드는 하나의 실행 단위이다. 따라서 스레드가 할 일을 모두 마치면 스레드는 Stopped 상태가 된다. 또한 작업 도중에 Abort() 함수를 호출해도 스레드는 종료하게 된다. 이렇게 해당 스레드의 함수가 끝나거나 리턴된 경우 또는 강제로 종료될 경우 스레드는 Stopped 상태가 된다.


Thread의 상태를 정확히 알아야만이 스레드를 제어할 수 있다. Thread의 속성을 이용하면 현재 스레드의 상태와 우선권 등 다양한 정보들을 얻을 수 있다.


▣ Main 스레드

public class MainThreadTest

{

public static void Main()

{

Thread th =Thread.CurrentThread;

Console.WriteLine("1. 현재 Thread HashCode:" + th.GetHashCode());

Console.WriteLine("2. 스레드의 이름:" + th.Name);

Console.WriteLine("3. 스레드의 CurrentCulture:" + th.CurrentCulture);

Console.WriteLine("4. 스레드의 우선순위:" + th.Priority);

Console.WriteLine("5. 스레드의 상태:" + th.ThreadState);

Console.WriteLine("6. 스레드의 IsBackground:" + th.IsBackground);

}

}

진입점이 있는 C# 애플리케이션은 기본적으로 하나의 스레드이다. C#에서는 프로그램의 시작을 나타내는 Main() 함수가 가장 기본적인 스레드이다. 그래서 스레드와 관련해서 Main() 함수를 Primary Thread라고 부르기도 한다.


☞ 스레드와 함수의 관계

:스레드라는 판 위에 함수가 동작한다고 생각하라. Main() 함수도 하나의 스레드 위에서 실행되는 방식으로 동작한다. 2개의 스레드를 만들고 각각의 스레드에 함수를 하나씩 올려서 동시에 실행하면 다중 스레드가 된다.

'C#' 카테고리의 다른 글

[C#] 요점정리  (0) 2018.07.16
[C#] 배열 복사  (0) 2018.07.16
[C#] Naming 규칙  (0) 2018.07.16
[C#] MemberwiseClone() 함수  (0) 2018.07.16
[C#] enum의 Flag 연산  (0) 2018.07.16