소스 코드 올립니다..

개학하면 바뻐서 업데이트 할 시간이 자주 없을듯 하네요..--;;

4학년 되면 취업준비한다고 바쁠테고.. 암튼 소스코드 올립니다. 언젠가는 더이상 업데이트 못 할날이 올지도 모르기 때문에..

솔직히 업데이트 하는게 기본적인틀이 잡혀 있어 어렵지는 않은데 약간은 귀찮네요..--;; 버그들도 많이 있는데.. 솔직히 손데면 일이 커질지도 모르고.. 귀찮고 해서요..

신고

멀티 쓰레드를 사용하고 프로그램이 작성가능하다면 좋겠지만, 실제 멀티 쓰레드를 사용하지 않고 프로그램을 작성하게 될경우 매우 복잡하게 되거나 구현이 불가능한 경우가 생기게된다.

예전에 만든 프로그램에서 멀티 쓰레드를 사용하지 않고, 짧은 간격으로 리턴하고, TIMER 이벤트로 호출하는 방법을 쓴적이 있다.

문제는 리턴하기 때문에 현재 수행한 상태를 저장해 두고 리턴 했고, 타이머에 의해서 호출되면 스위치 문에 의해 다시 이전 수행을 이어서 하게 만들었다.

그 뿐만 아니라 프로그램을 읽기가 매우 힘들고 유지하기도 어려웠다.

멀티 쓰레드는 또한 자원의 활용도를 높여 줘 시스템의 성능 또한 높여주게 된다.

//실제 수행 가능한 소스는 아니고 예제 입니다.

#define RUN_FLAG 1;
#define END_FLAG 2;

Class CTest
{
private:
  int m_threadFlag;
  CWinThread* m_threadMacro;
  //동시에 접근 하지 못하도록 막음
  CCriticalSection critical;
public:
  void run(void);
  void stop(void);
  void stopForce(void);
  int getListSize();
  void doSomething(void);
}

//수행 쓰레드를 시작
void CTest::run(void)
{
  m_threadFlag = RUN_FLAG;
  m_threadMacro = AfxBeginThread (macroThread,&*this);
}

//쓰레드를 종료
void CTest::stop(void)
{
  m_threadFlag = END_FLAG;
}

//강제로 쓰레드 종료
void CTest::stopForce(void)
{
  m_threadMacro->SuspendThread();
}

//크릭티칼 섹션이 필요한 경우
void CTest::doSomething(void)
{
  critical.Lock();
  //필요한 작업
  critical.Unlock();
}


//쓰레드 함수
UINT macroThread( LPVOID pParam )
{
  CTest* ct = ((CTest*)pParam);
  
  for(int i = 0; i < ct->geListSize(); i++)
  {
    //플래그가 종료일 경우 return함
    if(ct->getThreadFlag == END_FLAG) return 0;
    ct->doSometing(void);
  }
  
  return 0;
}



UINT macroThread( LPVOID pParam )


쓰레드로 수행될 함수를 전역 함수로 만든다. 파라미터는 LPVOID한개를 가지게 된다.

쓰레드에 넘겨줘야 할 값이 있으면 이 파라미터 한개로 넘겨주면된다. 갯수가 하나이기 여러개의 값을 넘겨주기 위해서는  때문에 구조체나 클래스 객체에 담아서 넘겨줘야 한다.

AfxBeginThread (macroThread,&*this);


아래와 같은 함수를 수행하게 되면 새로운 쓰레드가 생성되고 쓰레드가 시작된다.

반환 값은 CWinThread* 이다.

//플래그가 종료일 경우 return함
if(ct->getThreadFlag == END_FLAG) return 0;

일반적으로 쓰레드가 종료될 필요가 있으면 위와 같이 종료 플래그에 의해서 종료하면 된다.  이런 방식이 불가능할 경우는 아래와 같은 방법을 사용할 수 있다.

m_threadMacro->SuspendThread();


위와 같이 강제로 종료해도 되지만, 위와 같이 강제로 종료하게 될 경우, 쓰레드가 수행 도중 종료되게 된다. 위 예제에서는 doSometing()함수 호출되어 뭔가 하는 도중 일을 끝마치지 못한 상태에서 종료될 수도 있게된다.

이렇게 되더라도 특별한 문제가 없는 경우 위와 같이 종료하면되고, 문제 발생의 소지가 있다면 필요에 따라 조치를 취해줘야 한다.

critical.Lock();
//필요한 작업 Critical Section
critical.Unlock();


동기화가 필요할 경우에는 다음과 같이 동기화를 위해 lock과 unlock이 가능하다.

CCriticalSection critical;


같은 CCriticalSection 객체의 Critical Section에는 하나의 쓰레드만 수행되게 된다. Lock을 걸게 되면 다른 쓰레드에서는 이 부분에서 Unlock()이 될때 까지 기대리게 된다..
신고


티스토리 툴바