WideStudio/MWT Logo
WideStudio/MWT
Programming Guide
WideStudio/MWT Index
Table of contents


쓰레드 클래스와 진척 대화 상자에 의한 장시간 처리를 실행하기



쓰레드 클래스와 진척 대화 상자에 의한 장시간 처리를 실행하기

WSCvthread 클래스와 WSCworkingDialog를 사용하면, 장시간 걸리는 처리를 실행중이라도, 화면 묘화를 중단하지 않고 실행할 수 있습니다.

여기서 간단하게 예를 나타내면서, 쓰레드와 진척 대화 상자를 실장할 방법에 대해서 설명합니다. 누름 단추를 클릭하면, 시간이 걸리는 처리를 자식 쓰레드위에서 실행하고, 진척 대화 상자를 표시하는 응용프로그램을 작성합니다.

먼저, 새 창을 한개 만들어서, 누름단추를 배치합니다. 그리고 WSCworkingDialog와 WSCvthread 클래스의 인스턴스를 각각 배치하여, 명칭을 각각 newwork_001, newvthr_002라고 짓습니다.

누름단추에 다음과 같은 이벤트 프로시저 btnop()을 설정하고, 시간이 걸리는 처리를 자식 쓰레드위에서 실행하면서, 진척 대화 상자를 표시합니다. 프로그램안에 있는 프래그(flag) dialog_vis_status 는, 진척 대화 상자의 popup() 메서드에 의하는 표시가 종료한 것을, 처리중인 자식 쓰레드에 전달하기를 위한 프래그입니다. 진척 대화 상자가 취소된 경우, popup()가 끝난 후에, 프래그를 False에 병경하면, 자식 쓰레드에서 진척 대화 상자가 비표시 상태로 전환된 것을 분명히 알 수 있습니다.

#include <WScom.h>
#include <WSCfunctionList.h>
#include <WSCbase.h>
//----------------------------------------------------------
//Function for the event procedure
//----------------------------------------------------------
#include <newwin000.h>
//진척 대화 상자가 표시상태이는지 나타내는 프래그(flag)
WSCbool dialog_vis_status = False;

void btnop(WSCbase* object){
  //do something...
  dialog_vis_status = True; //쓰레드를 생성할 전에 프래그를 설정.
  //쓰레드를 생성하고, 처리를 실행한다.
  newvthr_002->executeThread();
  //대화 상자를 표시 상태로 전환한다.
  newwork_001->popup(); //(주의 사항) 대화 상자가 비표시 상태에 전환할 때까지 끈나지 않는다.
  dialog_vis_status = False;
}
static WSCfunctionRegister  op("btnop",(void*)btnop);

그 다음에, WSCvthread 클래스의 인스턴스 newvthr_002에 대해서, 자식 쓰레드로서 실행할 처리를 기술한 이벤트 프로시저 thread_proc()을 THREAD-STARTED 트리거(trigger)로 설정합니다. 진척 대화 상자에서 언제든지 취소할 수 있도록 자식 쓰레드로서 실행할 이벤트 프로시저를 기술할 때에 중요한 점은, 장시간 걸리는 처리를 짤막하게 나누어서 조금씩 처리를 실행할 점입니다. 아래 나타내는 에제는, 긴 처리 전체를 100회로 나누어서 실행해서, 변수 cnt로 회수를 셈합니다. 그리고, 그 회수를 그대로 진척 대화 상자에서 표시를 위해서 이용합니다.

#include <WScom.h>
#include <WSCfunctionList.h>
#include <WSCbase.h>
#include <unistd.h>
//----------------------------------------------------------
//Function for the event procedure
//----------------------------------------------------------
#include <newwin000.h>
extern long cnt;
extern WSCbool dialog_vis_status;
void thread_proc(WSCbase* object){
  cnt=0;
  while(1){
    //처리 진척 상황을 나타내는 숫자를 증가기킵니다.
    cnt++;
    //숫자 값을 진척 대화 상자에 반영시키기를 위해서,
    //부모 쓰레드에서 ACTIVATE 트리거로 이벤트 프로시저를 실행합니다.
    newvthr_002->sendActivateEvent();

    if (dialog_vis_status == False){
      //대화 상자가 비표시 상태, 즉 취소된 경우, 처리를 종료합니다.
      return;
    }
    if (cnt > 100){
      //짤막하게 나눈 처리를 100회 실행했던 경우, 처리를 종료합니다.
      return;
    }

    //여기서 장시간 걸리는 처리를 짤막하게 나누어서 조금씩 실행힙니다.
#ifdef MSW
    Sleep(1000);
#else
    sleep(1);
#endif
  }
}
static WSCfunctionRegister  op("thread_proc",(void*)thread_proc);

인스턴스는 기본적으로 쓰레드에 대해서 안전하지 않기 때문에, 진척 대화 상자에 숫자 값을 표시시키기를 위해서는, sendActivateEvent() 메서드를 사용해서, 부모 쓰레드위에서 ACTIVATE를 의한 이벤트 프로시저를 기동해서, 거기서 진척 대화 상자에 접근해야 합니다.

#include <WScom.h>
#include <WSCfunctionList.h>
#include <WSCbase.h>
//----------------------------------------------------------
//Function for the event procedure
//----------------------------------------------------------
#include <newwin000.h>
long cnt = 0;
void act_ep(WSCbase* object){
  //진척 상황을 나타내는 숫자 값을 속성으로서 설정합니다.
  newwork_001->setProperty(WSNvalue,cnt);

  //숫자 값이 100을 넘긴 경우, 대화 상자를 비표시 상태로 전환하고,
  //처리를 끝마칩니다.
  if (cnt>100){
    newwork_001->setVisible(False);
  }
}
static WSCfunctionRegister  op("act_ep",(void*)act_ep);



범용 쓰레드 클래스와 진척 대화 상자에 의하는 장시간 처리를 실행하기

WSDthread 클래스와 WSCworkingDialog를 사용하는, 처리 시간이 걸리는 처리를 실행하는 에제를 나타냅니다.

새 창을 한개 만들어서, 누름단추를 배치합니다. 그리고, WSCworkingDialog 클래스의 인스턴스를 배치해서, 명칭을 newwork_000라고 짓습니다.

누름단추에 다음과 같은 이벤트 프로시저 btnop()을 설정하고, 시간이 걸리는 처리를 자식 쓰레드위에서 실행하면서, 진척 대화 상자를 표시합니다.

프래그 canceled를 사용한 안전히 자식 쓰레드를 취소할 방법, 및 WSDthread::terminateThread() 메서드를 사용한 강제적으로 자식 쓰레드를 정지하는 방법을 나타냅니다. WSDthread::terminateThread() 메서드에 의한 자식 쓰레드를 정지하기는, 처리중에 강제적으로 정지하기 때문에, 파일 자원를 제어하기등, 자원제어 처리에는 맞지 않습니다.



자식 쓰레드를 강제 종료시키는 에제입니다.

#include <WScom.h>
#include <WSCfunctionList.h>
#include <WSCbase.h>
#include <WSDthread.h>
#include <stdlib.h>
#include <unistd.h>
//----------------------------------------------------------
//Function for the event procedure
//----------------------------------------------------------
#include <newwin000.h>
WSDthread* thr = NULL;
WSCbool canceled = False;

//자식 쓰레드로서 동작하는 프로시저
void* thread_func(WSDthread* obj,void*){
  //진척 상황을 나타내는 숫자
  long cnt= 0;
  while(1){
    //숫자를 증가합니다.
    cnt++;
    //숫자 값을 진척 대화 상자에 표시하기를 위해서,
    //부모 쓰레드위에서 프로시저를 실행합니다.
    obj->execCallback((void*)cnt);


    //여기서 장시간 걸리는 처리를 짤막하게 나누어서 조금씩 실행힙니다.
#ifdef MSW
    Sleep(1000);
#else
    sleep(1);
#endif

    //숫자 값이 100을 넘긴 경우, 처리를 끝냅니다.
    if (cnt == 100){
      return NULL;
    }
  }
  return NULL;
}

//숫자 값을 진척 대화 상자에 반영시키기를 위하는 프로시저
//WSDthread::execCallback() 메서드에 의해서 부모 쓰레드에서 실행된다.
void callback_func(WSDthread*,void* val){
  long cnt = (long)val;
  //숫자 값을 진척 대화 상자에 반영
  newwork_000->setProperty(WSNvalue,cnt);
  if (cnt == 100){
    newwork_000->setVisible(False);
  }
}

//버튼 클릭에 의해서, 진척 대화 상자를 표시하고, 처리를 시작.
void btnop(WSCbase* object){
  if (thr == NULL){
    //쓰레드 인스턴스를 생성.
    thr = WSDthread::getNewInstance();
    //자식 쓰레드로서 실행하는 프로시저를 설정.
    thr->setFunction(thread_func);
    //자식 쓰레드에서 호출되는
    //부모 쓰레드에서 실행되는 콜백 프로시저를 설정.
    thr->setCallbackFunction(callback_func);
    //자식 쓰레드를 생성.
    thr->createThread(NULL);
    //진척 대화 상자를 표시.
    long val = newwork_000->popup();
    if (val == WS_DIALOG_OK){
    }else{
      //자식 쓰레드를 강제 종료할 경우.
      thr->terminateThread();
    }
  }else{
    exit(0);
  }
}
static WSCfunctionRegister  op("btnop",(void*)btnop);

자식 쓰레드를 프래그(flag)를 참조하여 안전히 종료하는 예제입니다.

#include <WScom.h>
#include <WSCfunctionList.h>
#include <WSCbase.h>
#include <WSDthread.h>
#include <stdlib.h>
#include <unistd.h>
//----------------------------------------------------------
//Function for the event procedure
//----------------------------------------------------------
#include <newwin000.h>
WSDthread* thr = NULL;
WSCbool canceled = False;

//자식 쓰레드로서 동작하는 프로시저
void* thread_func(WSDthread* obj,void*){
  //진척 상황을 나타내는 숫자
  long cnt= 0;
  while(1){
    //숫자를 증가합니다.
    cnt++;
    //숫자 값을 진척 대화 상자에 표시하기를 위해서,
    //부모 쓰레드위에서  프로시저를 실행합니다.
    obj->execCallback((void*)cnt);

    //여기서 장시간 걸리는 처리를 짤막하게 나누어서 조금씩 실행힙니다.
#ifdef MSW
    Sleep(1000);
#else
    sleep(1);
#endif

    //숫자 값이 100을 넘긴 경우, 처리를 끝냅니다.
    if (cnt == 100){
      return NULL;
    }
    //프래그(flag)를 참조하고, 처리를 중지해야 하는가를 판단합니다.
    if (canceled != False){
      return NULL;
    }
  }
  return NULL;
}

//숫자 값을 진척 대화 상자에 반영시키기를 위하는 프로시저
//WSDthread::execCallback() 메서드에 의해서 부모 쓰레드에서 실행된다.
void callback_func(WSDthread*,void* val){
  long cnt = (long)val;
  //숫자 값을 진척 대화 상자에 반영.
  newwork_000->setProperty(WSNvalue,cnt);
  if (cnt == 100){
    newwork_000->setVisible(False);
  }
}

//버튼 클릭에 의해서, 진척 대화 상자를 표시하고, 처리를 시작.
void btnop(WSCbase* object){
  if (thr == NULL){
    //쓰레드 인스턴스를 생성.
    thr = WSDthread::getNewInstance();
    //자식 쓰레드로서 실행하는 프로시저를 설정.
    thr->setFunction(thread_func);
    //자식 쓰레드에서 호출되는
    //부모 쓰레드에서 실행되는 콜백 프로시저를 설정.
    thr->setCallbackFunction(callback_func);
    //자식 쓰레드를 생성.
    thr->createThread(NULL);
    //진척 대화 상자를 표시.
    long val = newwork_000->popup();
    if (val == WS_DIALOG_OK){
    }else{
      //자식 쓰레드에 처리를 중지시킵니다.
      canceled = True;
    }
  }else{
    exit(0);
  }
}
static WSCfunctionRegister  op("btnop",(void*)btnop);


Document Release 3.90 for WideStudio/MWT ver 3.90, Jul 2005


WideStudio/MWT documents index | Table of contents

Copyright(C) WideStudio/MWT Development Team, 1999-2005 Last modified: Jul 31, 2005