C#,Delphi,Oracle,MSSQL 개발자블로그

스레드 다루기 - 1. 스레드의 개념이해 본문

Programming/C#

스레드 다루기 - 1. 스레드의 개념이해

19760323 2017. 3. 12. 18:39

이번 강좌에서는 스레드를 다루어 볼 것입니다. 스레드는 네트워크 프로그램만 아니라 비동기 처리나 동시 다발적인 프로그래밍을 하기 위해서는 반드시 알아야 할 개념입니다. 스레드의 깊이는 굉장히 깊습니다. 이 책에서는 깊은 스레드의 내용 중에서도 반드시 알아야 내용들만 다루게 볼 것입니다. 중요한 부분이기 때문에 그냥 지나치지 말고 학습하고 넘어 가기 바랍니다.


1. 스레드 개념 이해하기


스레드는 CPU의 가장 작은 실행 단위입니다. 우리가 만들게 될 게임 같은 프로그램은 프로세스에 해당 됩니다. 스레드는 그 프로세스에 안에서 실행되는 작은 실행 단위의 개념입니다. 그렇기 때문에 하나의 프로세스에는 여러 개의 스레드가 존재 하게 됩니다. 아래 그림을 보고 좀더 구체적으로 이해해 봅시다.


우리는 현재 32bit의 운영체제 환경에서 컴퓨터를 다루고 있습니다. 16bit 당시의 환경에서 32bit로 업그레이드 된 것은 많은 발전이였습니다. 16bit 환경은 단일 프로세스만 실행할 수 있었지만 32bit는 CPU안에 여러 프로세스를 실행 할 수 있기 때문인 것이죠. 이것은 단일 프로세스 밖에 작동 할 수 밖에 없었던 이전 16bit 환경에 엄청난 편의를 가져온 것입니다.

그렇다면 스레드는 무엇일까요? 좀 더 구체적인 예를들어 설명해 보겠습니다. VS.NET2005 편집기를 실행하였습니다. 분명 VS.NET2005라는 하나의 프로세스로 실행 되고 있습니다. 하지만 동작은 여러 개가 분산되어 처리됩니다. 작성하고 있는 코드에 폰트 색을 편집해주는 작업, 코드의 문법이 올바른지 검사해서 밑줄을 쳐 주는 작업 등등의 이런 작고 작은 기능들이 분산되어 작동 되고 있습니다. 이런 작은 기능들이 바로 스레드로 작동되고 있는 것입니다. 작업관리자 창에서 윈도우에서 실행되는 프로세스와 스레드를 확인 할 수 있습니다. 작업관리자 창을 띄워보면 한 프로세스당 실행되고 있는 스레드의 개수를 확인 할 수 있습니다.



작업관리자에 스레드 열이 보이지 않는다면 메뉴-보기(V)에서 열 선택 메뉴 선택에서 스레드를 선택하기 바랍니다.

2. 스레드 선언하기
자 그럼 이제 스레드를 본격적으로 선언하고 사용하는 방법을 알아보도록 하겠습니다. 스레드는 ThreadStart라는 위임을 이용하여 선언할 수 있습니다. 아래 예제를 통해서 스레드를 선언하고 실행하는 방법을 살펴 봅시다.



using
System;
using System.Collections.Generic;
using System.Text;

using System.Threading;//스레드 네임스페이스 추가 

namespace SampleThread
{
    class Program
    {
        static void Main(string[] args)
        {
            //메서드실행
            ThreadSample();
            
            //스레드 선언하기

            ThreadStart ts = new ThreadStart(ThreadSample);

            Thread spThread = new Thread(ts);

            //스레드 작동
            spThread.Start();
 
        }

        static void ThreadSample()
        {
            Console.WriteLine("Thread Called");
            
            //스레드 아이디 출력

            Console.WriteLine("현재Thread ID : {0}",Thread.CurrentThread.ManagedThreadId);

        }
    }
}
 

결과

Thread Called

현재 Thread ID : 1

Thread Called

현재 Thread ID : 3


결과를 보면 알 수 있듯이 ThreadSample() 메서드를 두번 실행 하였습니다. 한번은 Main함수에서 ThreadSample을 실행 하였고(13줄), 한번은 메서드를 ThreadStart에 위임 시킨 후 스레드를 작동하여서 실행 하였습니다. 28줄은 현재 자신의 스레드 아이디를 가져와서 출력 하는 코드입니다. 같은 메서드를 실행하지만 현재 이 메서드를 실행하는 스레드는 다르다는 것을 알 수 있을 것입니다. 아래 그림을 살펴 봅시다.



그림에서는 매인 스레드에서 ThreadSample 메서드를 실행합니다. 그리고 새로운 스레드(spThread톱니바퀴)를 생성하여 역시 똑같이 ThreadSample 메서드를 실행하고 있습니다. 같은 메서드를 두번 실행하는 것이지만 서로 다른 스레드에서 실행하고 있는 것입니다.


3. 스레드 주요멤버
스레드 클래스를 작동하고 관리하는 주요 멤버들을 살펴 보도록 하겠습니다.
 
● 스레드의 주요 메서드

스레드의 동작을 제어하는 주요한 메서드들을 살펴 봅시다.
 

Abort()

스레드를 종료 프로세스를 실행시켜 강제 종료합니다.

Interrupt()

WaitSleepJoin 스레드 상태 즉, 대기 중인 스레드를 중단합니다.

Join()

스레드가 종료될 때까지 호출 스레드를 차단합니다.

Sleep()

지정된 시간(밀리초)동안 스레드를 쉬게 합니다.

Start()

현재 스레드의 상태를 Running으로 변경합니다.(스레드 시작)


 ● 스레드의 주요 속성
현재 스레드의 상태를 가져오거나 설정하기 위해서 사용되는 속성들을 살펴 봅시다.  

 

CurrentCulture

현재 스레드에 대한 culture를 가져오거나 설정합니다.

CurrentUICulture

리소스 관리자가 런타임에 culture 관련 리소스를 찾기 위해 사용하는 현재 culture를 가져오거나 설정합니다.

IsAlive

현재 스레드의 실행 상태를 나타내는 값을 가져옵니다.

IsBackground

스레드가 배경 스레드인지 여부를 나타내는 값을 가져오거나 설정합니다.

IsThreadPoolThread

스레드가 관리되는 스레드 풀에 속하는지 여부를 나타내는 값을 가져옵니다.

Name

스레드의 이름을 가져오거나 설정합니다.

Priority

스레드의 예약 우선 순위를 나타내는 값을 가져오거나 설정합니다.

ThreadState

현재 스레드의 상태를 포함하는 값을 가져옵니다.

  

이제 예제를 통해서 스레드의 상태를 출력 해 보도록 하겠습니다. 


using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;//스레드네임스페이스
 
namespace SampleThread
{
    class Program
    {
        static void Main(string[] args)
        {
            //스레드선언하기
            Program tsObject = new Program();
            Thread spThread = new Thread(new ThreadStart(tsObject.ThreadSample));

             Console.WriteLine("현재스레드상태: {0}", spThread.ThreadState);

            //스레드시작하기
           spThread.Start();
            Console.WriteLine("현재스레드상태: {0}", spThread.ThreadState);
            Console.WriteLine("현재 스레드IsAlive? : {0}", spThread.IsAlive);

            
            //스레드정지하기
            spThread.Abort();
            Console.WriteLine("현재 스레드 상태: {0}", spThread.ThreadState);
 
        }

        public void ThreadSample()
        {
            //스레드를 1초간 쉬게한다.
            Thread.Sleep(1000);
        }
    }
}




 

현재 스레드 상태: Unstarted

현재 스레드 상태: WaitSleepJoin

현재 스레드 IsAlive? : True

현재 스레드 상태: AbortRequested


 ThreadSample() 메서드에 Thread.Sleep(1000)에 주석을 달고 실행을 해 보면 아래와 같은 결과가 나오게 됩니다.

현재 스레드 상태 : Unstarted

현재 스레드 상태 : Stopped

현재 스레드 IsAlive? : True

현재 스레드 상태 : Stopped


즉, 스레드의 상태를 출력하고, Abort()를 실행하기도 전에 이미 스레드는 종료 된 것입니다.



출처 : http://www.hoons.net/lecture/view/126

Comments