본문 바로가기
Borland

Thread Test Program[WaitForMultipleObjects()]

by leo21c 2009. 8. 11.

Thread Test Program

첨부파일은 C++Builder 6.0으로 제작되었다.

1249972417_Thread_Test2.zip

1. 테스트 내용

- method 1: jpg 파일 50개를 Serial 하게 읽어 RGB반전 후 다른이름으로 저장

- method 2: thread 50개를 만들어 각 Thread가 jpg 파일을 읽어 RGB반전 후 다른이름으로 저장

2. 사용되는 API 함수

- TThread Class 상속 Class 이용: CreateThread()함수와 유사

- WaitForMultipleObjects(): Thread가 signal 되는 것을 확인하기 위한 함수

3. Header

//---------------------------------------------------------------------------

#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

4. cpp

//---------------------------------------------------------------------------

#include <vcl.h>

#pragma hdrstop

#include "Unit1.h"

#include "JPEG.hpp"

//---------------------------------------------------------------------------

#define THREAD_COUNT 55 // ß----- Thread 개수

//---------------------------------------------------------------------------

#pragma package(smart_init)

#pragma resource "*.dfm"

TForm1 *Form1;

//---------------------------------------------------------------------------

__fastcall TForm1::TForm1(TComponent* Owner)

: TForm(Owner)

{

defaultDir = "C:\\Temp_Image\\"; // ß----- jpg 이미지가 있는 폴더

InitializeCriticalSection(&crit);

}

//---------------------------------------------------------------------------

/// JPG 파일 오픈, RGB 반전, 다른 이름으로 저장하는 함수

void __fastcall TForm1::ConvertImage(Graphics::TBitmap* bitmap, int index, int kind)

{

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;

}

//---------------------------------------------------------------------------

/// Serial하게 파일을 처리하는 함수를 처리하는 버튼

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]; // ß---Thread class 변수 배열

HANDLE handle[THREAD_COUNT]; // ß--- Thread handle 배열

/// Thread로 파일을 처리하는 함수를 처리하는 버튼

void __fastcall TForm1::Button2Click(TObject *Sender)

{

DWORD dwWaitResult;

AnsiString return_result;

Label3->Caption = TimeToStr(Time()); // ß--- 시작하기 전에 현재 시간 표시

index = 0;

int i, k;

for (i = 0; i < THREAD_COUNT; i++) {

thread[i] = new ImpThread(i);

handle[i] = (HANDLE)thread[i]->Handle;

}

Sleep(10);

dwWaitResult = WaitForMultipleObjects(THREAD_COUNT, handle, TRUE, INFINITE);

int count = dwWaitResult - WAIT_OBJECT_0;

if (WAIT_OBJECT_0 >= dwWaitResult && WAIT_OBJECT_0+ THREAD_COUNT - 1 >= dwWaitResult) {

//Label4->Caption = "success";

Label4->Caption = TimeToStr(Time());

}

else if (WAIT_FAILED == dwWaitResult) {

return_result = GetLastError();

//Label4->Caption = return_result;

Label4->Caption = TimeToStr(Time());

}

else if (WAIT_TIMEOUT == dwWaitResult) {

//Label4->Caption = "time out";

Label4->Caption = TimeToStr(Time());

}

else if (WAIT_ABANDONED_0 == dwWaitResult) {

//Label4->Caption = "WAIT_ABANDONED_0";

Label4->Caption = TimeToStr(Time());

}

else {

//Label4->Caption = "fail";

Label4->Caption = TimeToStr(Time());

}

for (i = 0; i < THREAD_COUNT; i++) {

delete thread[i];

thread[i] = NULL;

handle[i] = NULL;

}

}

//---------------------------------------------------------------------------

//CreateSuspended 인자를 false로 하면 생성 즉시 시작하게 된다.

//일반적인 Thread는 ture를 가지며 생성 하지만 실행되지 않는다.

__fastcall ImpThread::ImpThread(int index)

: TThread(false)

{

Priority = tpTimeCritical;

Index = index;

defaultDir = "C:\\Temp_Image\\";

}

//---------------------------------------------------------------------------

/// Thread에러 실행 하는 함수

void __fastcall ImpThread::Execute()

{

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;

return;

}

//---------------------------------------------------------------------------