C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 Q&A
C++Builder Programming Q&A
[57971] TThread 테스트 프로그래밍 중에 WaitForMultipleObjects()함수 문제
leo21c [leo21c] 1974 읽음    2009-08-07 16:48
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);
}
//---------------------------------------------------------------------------

+ -

관련 글 리스트
57971 TThread 테스트 프로그래밍 중에 WaitForMultipleObjects()함수 문제 leo21c 1974 2009/08/07
58004     Re: 반환값 검사가 잘못되었어요 ㄱㄴ 1691 2009/08/11
58012         답변 감사합니다. leo21c 1152 2009/08/11
57998     Re:TThread 테스트 프로그래밍 중에 WaitForMultipleObjects()함수 문제 김진호.불사새 1864 2009/08/10
58003         bWaitAll을 TRUE로 세팅한 것은 모든 Thread를 기다리기 위해서입니다. leo21c 1497 2009/08/11
57996     Re:TThread 테스트 프로그래밍 중에 WaitForMultipleObjects()함수 문제 ㄱㄴ 2042 2009/08/10
57981     Re:Thread 테스트 프로그래밍 중에 WaitForMultipleObjects()함수 문제 ㄱㄴ 1229 2009/08/09
57991         TThread의 Handle과 CreateThread의 ThreadID와 같지 않나요? leo21c 1886 2009/08/10
57994             Re:TThread의 Handle과 CreateThread의 ThreadID와 같지 않나요? 장성호 1819 2009/08/10
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.