2009년 8월 15일 토요일

멀티스레드 구현하기(threadpool)

먼저 스레드가 무엇인지 부터 알고 넘어가야겠죠?

컴퓨터 상에서 프로그램을 실행시키면 프로세스라고 부르는 하나의 일관된 작업이 일어나게 됩니다.

여기에서 하나의 프로세스 상에서 일어나는 행위를 스레드 라고 부르면 될꺼 같습니다.

 

그리고 멀티 스레드란 하나의 프로세스에서 두개이상의 스레드가 동시 또는 순차적으로 일어나는 행위를 가르켜 멀티 스레드 라고 부릅니다.

 

이해를 돕기 위해서 싱글 스레드와 멀티 스레드의 개념도를 그려 보았습니다.

 

 

 

 

 

 

머리속에 있는 스레드의 개념을 대충 그려서 올려봤습니다.

 

1번과 2번은 언뜻 보기에 처리 시간이 비슷하게 보일지모르지만

처리 과정에서 CPU idletime이 생기는 동안에 다른 스레드가 CPU에 올라가서작업을하기 때문에

실제로는 1번보다 2번이 빨리 종료하게 됩니다.

3번이야 눈으로도 빨리 끝나는걸 알 수 있겠네요..^^

 

그럼 이쯤하고 오늘 소개해드릴 C#에서의 멀티 스레드기능을 알아 보겠습니다.

 

멀티 스레드 구현방법의 시나리오를먼저 설명 하겠습니다.

 

미션: 파일로 받은 2개의 대용량 DATA 를 편집하여 SQL SERVER의 각각의 테이블에 등록하고

그런다음 두개의 테이블을 조인하여 최종테이블에 등록하기.(여기에서 발생할 멀티 스레드 부분)

 

로직을 짠다면 A 파일데이터를 A 테이블에 집어 넣고 , 그런다음 B 파일 데이터를 B테이블에 집어 넣은다음

A 테이블과 B 테이블을 조인하여 C 테이블에 등록하면 끝 입니다.

 

그러나 두개의 파일이 워낙 대용량이고 처리시간은 한정되어있다면 멀티 스레드를 이용하는게 좋습니다.

class SampleThread
{
static void Main()
  {

       // 먼저 Athread와 Bthread를 생성 합니다.
       Thread Athread = new Thread();

       Thread Bthread = new Thread();
       Athread = new Thread(new ThreadStart(InsertTableA()));

       Bthread = new Thread(new ThreadStart(InsertTableB()));

 

       Athread.Start();

       Bthread.Start();

 

       // Main thread처리

 

       Athread.Join();

       Bthread.Join();

 

 

 

       // Main thread처리


       Console.Write("END”);

   }

}

스레드 풀을 이용한 예제

class ThreadPoolSample
{
    static int JoinCount = 0;
    static void Join() // join
    {
        if( Interlocked.Decrement( ref JoinCount )==0 ) {
            WaitCallback callbackC=new WaitCallback( ThreadPoolSample.Cthread );
            ThreadPool.QueueUserWorkItem( callbackC );
        }
    }
    static void Athread ( object stateInfo )
    {
        // insertAtable
        Join();
    }
    static void Bthread ( object stateInfo )
    {
        // insertBtable
        Join();
    }
   
    static void Cthread ( object stateInfo )
    {
        // backgroundC
    }
    public static void Main()
    {
        WaitCallback callbackA=new WaitCallback( ThreadPoolSample.Athread );
        Interlocked.Increment( ref JoinCount );
        ThreadPool.QueueUserWorkItem( callbackA );
        WaitCallback callbackB=new WaitCallback( ThreadPoolSample.Bthread );
        Interlocked.Increment( ref JoinCount );
        ThreadPool.QueueUserWorkItem( callbackB );
        // main thread keep going
    }
}

 

댓글 없음:

댓글 쓰기