쓰레드 ㅠ_ㅡ
Posted 2007. 6. 1. 11:58, Filed under: Study/Computer Sciencevoid CHpCntDlg::OnOK() {
UpdateData(TRUE);
HpCounter* hpc = new HpCounter(dlg);
// Homepage upload count
hpc->MakeTmp(); // make temporary folder
GetDlgItem(hWnd ,IDC_STEP)->SetWindowText("홈페이지 업로드 카운트 중...");
pHpthread = AfxBeginThread(threadHompageCnt, hpc);
if( m_CheckINI == TRUE){
hpc->WriteINICnt();
}
// Sample Count
GetDlgItem(IDC_STEP)->SetWindowText("엔진 샘플 수 카운트 중...");
SpCounter* spc = new SpCounter(this);
pSptread = AfxBeginThread(threadSampleCnt, spc);
pSptread->SuspendThread();
...
}
------
1. Ok 버튼을 눌렀을 때 수행되는 위의 프로시져가 웹페이지를 다운로드해서 파싱하고 결과를
출력하는 시간이 꽤 걸리는 작업이라서 창을 다시 그려줄 때 깨지거나 응답없음이 나타난다.
2. 쓰레드를 이용해서 내부 프로시져가 돌아가는 거랑 창을 그려주는 걸 별도로 수행하도록 하면
해결할 수 있음.
3. 쓰레드를 생성하기 위해서는 UINT 함수이름(LPVOID pParam); 와 같은 형식의 쓰레드에서
실행하는 처리를 당담하는 프로시저가 필요함
(형식의 제한이 있어서 복잡한 파라미터를 넘겨주는 함수를 구현할 수가 없었다.
이럴 때는 파라미터를 모두 가지는 구조체를 선언하여 그 포인터를 넘기면 된다고 한다.)
4. 쓰레드를 생성할 때는 CreateThread 윈도우 API 보다는 AfxBeginThread를 사용하는 것이 바람직
C/C++의 표준 라이브러리를 사용하는 경우 프로세스 내의 스레드는 메모리 공간을 공유하기 때문에 정적 변수 사용등에 있어서 문제가 발생한다. (예: strtok) 이를 방지하기 위해서 윈도우에서 쓰레드마다 다른 메모리 영역을 정적으로 할당(TLS: Thread Local Storage) 이 때 TLS를 사용하기 위해서는 쓰레드를 생성할 때 초기화 등의 준비가 필요한데 CreateThread를 사용해 쓰레드를 생성하면 이런 처리를 할 수 없다.
5. 쓰레드 함수 내에서는 GetDlgItem() 함수를 호출할 수 없음. (쓰레드 함수는 전역으로 선언되어있고 윈도우(다이얼로그) 내부의 함수가 아니므로) 그리하여 GetDlgItem 부분은 OnOK() 함수에서 처리하고 나머지를 둘로 나누어 각각 쓰레드로 처리하려고 했는데.. 그렇게 했더니 파일 I/O 가 있는 부분에서 대기하는 동안 제어가 다른 쓰레드로 넘어가면서 병렬로 처리되고 결과가 제대로 안나온다. 순차적으로 처리해야하는 프로시저에서 분리를 목적으로 쓰레드를 사용하니까 참 맘대로 안된다.
6. 그래서 WaitForSingleObject() 를 사용해서 쓰레드 처리를 기다리려고 했는데. AfxBeginThread 함수나 CreateThread 함수는 쓰레드 생성에 성공하면 쓰레드 프로시저의 종료를 기다리지 않고 즉시 호출로부터 복귀한다. 그래서 WaitForSingleObject 가 별로 소용이 없다. 게다가 메인 프로시저는 쓰레드 프로시저의 상태와 상관없이 계속해서 프로그램을 실행하므로 출력루틴이 먼저 실행되는 사태가 발생해서 완전 결과가 엉망이 됐다.
7. 윈도우 자체를 쓰레드 프로시저에 넘겨주고 GetDlgItem를 호출할 수 있도록 만들려고 했는데 윈도우 핸들을 얻어오는게 맘처럼 쉽지가 않다 ;;
8. 쓰레드 핸들을 사용해서 한번 컨트롤 해봐야겠다..
쓰레드 너무 힘들다 ㅠ_ㅠ