|
Thread 테스트 프로그래밍 중에 WaitForMultipleObjects()함수 리턴값이 원한는 값이 나오지 않습니다.
Thread 공부중입니다.
WaitForMultipleObjects()함수는 생성된 Thread가 모두 종료 되면 그 개수를 리턴하는 것으로 알고 있습니다.
테스트 프로그램은 100개의 파일을 100개의 각각의 Thread가 jpg를 읽어 색을 반전하고 다시 다른이름으로
저장하도록 했습니다.
serial file open and convert, resave 하는 루틴과 thread로 처리한 루틴의 처리 시간을 비교하기 위해서
만들었습니다.
고수님의 조어 부탁드립니다.
WaitForMultipleObjects()의 리턴 값이 WAIT_OBJECT_0 + THREAD_COUNT - 1이 되지 않고 다르다고 나옵니다.
파일이 각각 다른기 때문에 파일을 처리하고, 접근(읽고, 쓰기) 할 때 동기화가 필요없다고 생각했습니다.
소스는 아래와 같습니다.
프로젝트는 첨부로 올렸습니다.
///////////////////////////////////////////////////////////////////////////////////////////////////
//test.h
//--------------------------------
//---------------------------------------------------------------------------
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
TButton *Button1;
TButton *Button2;
TLabel *Label1;
TLabel *Label2;
TLabel *Label3;
TLabel *Label4;
void __fastcall Button1Click(TObject *Sender);
void __fastcall Button2Click(TObject *Sender);
private: // User declarations
public: // User declarations
int check[30];
int index;
AnsiString defaultDir;
__fastcall TForm1(TComponent* Owner);
void __fastcall ConvertImage(Graphics::TBitmap* bitmap, int index, int kind = 0);
};
//---------------------------------------------------------------------------
class ImpThread : public TThread
{
private:
int Index;
AnsiString defaultDir;
protected:
void __fastcall Execute();
public:
__fastcall ImpThread(int index);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
//test.cpp
///////////////////////////////////////////////////////////////////////////////////////////////////
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "test.h"
#include "JPEG.hpp"
//---------------------------------------------------------------------------
#define THREAD_COUNT 100
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
CRITICAL_SECTION crit;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
defaultDir = "C:\\Temp_Image\\";
InitializeCriticalSection(&crit);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ConvertImage(Graphics::TBitmap* bitmap, int index, int kind)
{
EnterCriticalSection(&crit);
if (kind == 1) index++;
AnsiString filename = defaultDir + index;
filename += ".jpg";
TJPEGImage *pJpeg = new TJPEGImage();
pJpeg->LoadFromFile(filename);
bitmap->Assign(pJpeg);
Byte* ptr;
unsigned char pBuffR;
unsigned char pBuffG;
unsigned char pBuffB;
for (int y = 0; y < bitmap->Height; y++) {
ptr = (Byte *)bitmap->ScanLine[y];
for (int x = 0; x < bitmap->Width; x++) {
pBuffB = ptr[3*x];
pBuffG = ptr[3*x+1];
pBuffR = ptr[3*x+2];
ptr[3*x] = 255 - pBuffB;
ptr[3*x+1] = 255 - pBuffG;
ptr[3*x+2] = 255 - pBuffR;
}
}
pJpeg->Assign(bitmap);
filename = defaultDir;
if (kind == 0) filename += "normal\\";
else filename += "thread\\";
filename += index;
filename += "_r.jpg";
pJpeg->SaveToFile(filename);
delete pJpeg;
LeaveCriticalSection(&crit);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
Label1->Caption = TimeToStr(Time());
Graphics::TBitmap* bitmap = NULL;
for (int i = 1; i < THREAD_COUNT + 1; i++) {
bitmap = new Graphics::TBitmap;
ConvertImage(bitmap, i, 0);
delete bitmap;
}
Label2->Caption = TimeToStr(Time());
}
//---------------------------------------------------------------------------
ImpThread *thread[THREAD_COUNT];
HANDLE handle[THREAD_COUNT];
void __fastcall TForm1::Button2Click(TObject *Sender)
{
DWORD dwWaitResult;
Label3->Caption = TimeToStr(Time());
index = 0;
int i, k;
unsigned a;
for (i = 0; i < THREAD_COUNT; i++) {
thread[i] = new ImpThread(i);
a = thread[i]->Handle;
handle[i] = &a;
}
Sleep(10);
dwWaitResult = WaitForMultipleObjects(THREAD_COUNT, handle, TRUE, INFINITE);
if (WAIT_OBJECT_0 + THREAD_COUNT - 1 == dwWaitResult) {
Label4->Caption = TimeToStr(Time());
}
else {
//Label4->Caption = "fail"; //<--------이쪽으로 들어옵니다. 왜 그럴까요?????
Label4->Caption = TimeToStr(Time());
}
}
//---------------------------------------------------------------------------
//CreateSuspended 인자를 false로 하면 생성 즉시 시작하게 된다.
//일반적인 Thread는 ture를 가지며 생성 하지만 실행되지 않는다.
__fastcall ImpThread::ImpThread(int index)
: TThread(false)
{
Priority = tpTimeCritical;
Index = index;
defaultDir = "C:\\Temp_Image\\";
}
//---------------------------------------------------------------------------
void __fastcall ImpThread::Execute()
{
//EnterCriticalSection(&crit);
Graphics::TBitmap* bitmap = NULL;
bitmap = new Graphics::TBitmap;
int index = Index + 1;
AnsiString filename = defaultDir + index;
filename += ".jpg";
TJPEGImage *pJpeg = new TJPEGImage();
pJpeg->LoadFromFile(filename);
bitmap->Assign(pJpeg);
Byte* ptr;
unsigned char pBuffR;
unsigned char pBuffG;
unsigned char pBuffB;
for (int y = 0; y < bitmap->Height; y++) {
ptr = (Byte *)bitmap->ScanLine[y];
for (int x = 0; x < bitmap->Width; x++) {
pBuffB = ptr[3*x];
pBuffG = ptr[3*x+1];
pBuffR = ptr[3*x+2];
ptr[3*x] = 255 - pBuffB;
ptr[3*x+1] = 255 - pBuffG;
ptr[3*x+2] = 255 - pBuffR;
}
}
pJpeg->Assign(bitmap);
filename = defaultDir;
filename += "thread\\";
filename += index;
filename += "_r.jpg";
pJpeg->SaveToFile(filename);
delete pJpeg;
delete bitmap;
//LeaveCriticalSection(&crit);
}
//---------------------------------------------------------------------------
|