|
어제 저녁에 함 글 올렸다가 지우고 이러저러하게 다시 해보고 올립니당..
criticalsection으로 스레드간 동기화를 해보려하는데요.
간단히 테스트삼아 TCriticalSection 을 이용해서 ProgressBar를 2개의 스레드(메인 스레드 포함)에서 카운트 해보려하는데 동기화안하고 돌린것처럼 먹통이 되어 버립니다.
타이머 하나가 프로그레스바 카운트를 하구요.
TCriticalSection *CS = new TCriticalSection();
TThreadProc *ThreadProc;
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
Timer1->Enabled = false;
CS->Enter();
ProgressBar1->Position++;
if (ProgressBar1->Position >= ProgressBar1->Max)
ProgressBar1->Position = ProgressBar1->Min;
CS->Leave();
Timer1->Enabled = true;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
ThreadProc = new TThreadProc(false);
}
//---------------------------------------------------------------------------
버튼1을 누르면 스레드하나를 생성해서 마찬가지로 돌리는데..
extern TCriticalSection *CS;
//---------------------------------------------------------------------------
void __fastcall TThreadProc::Execute()
{
while (!Terminated)
{
Sleep(10); //임시로 넣음.
ChgUI();
}
}
//---------------------------------------------------------------------------
void __fastcall TThreadProc::ChgUI()
{
CS->Enter();
Form1->ProgressBar1->Position++;
if (Form1->ProgressBar1->Position >= Form1->ProgressBar1->Max)
Form1->ProgressBar1->Position = Form1->ProgressBar1->Min;
CS->Leave();
}
//---------------------------------------------------------------------------
영 잘 안됩니다. 어차피 Synchronize(ChgUI);를 해버리면 편하겠습니다만...
CriticalSection의 사용법이 잘못된건지 모르겠습니다.
신기한것은 criticalsection을 사용한 두 부분중 한곳을 지우고 실행하면 안죽고 잘만 돌아간다는 사실;;;
원래 공유변수에 접근하는 곳마다 임계영역을 지정해 줘야 되는거 아닌가요....
p.s.
검색중에 비슷한 경우가 있네요..유영인님이 synchronize를 사용하라는 답변을 올려놓으셨는데,
VCL접근시에는 그럼 꼭 synchronize만을 사용해야 하는건가요?
같은 동기화 목적으로 사용하는건데 criticalsection으로는 안되는건가요?
Synchronize소스를 보니 얼핏 내부에서 criticalsection을 사용하는것으로 보이는데 말이죠;;;
(Event관련도 보이는군...차이는 이것때문인가;;;;)
암튼...가장 중요한것은;;
VCL이외의 일반 데이터 변수(또는 클래스)들은 제가 위와같이 사용해도 문제없는거겠죠?-_-
|