|
답변이라기 보다는 참고 및 추가 질문입니다.
질문은 왜 TDowork::Execute()에서 Synchronize()를 사용했나하는 겁니다.
빌더의 Thread에서 메인 폼의 VCL Component를 사용하지 않는다면
Synchronize를 사용할 필요가 없습니다.
Thread각각 내부에서만 쓰는 VCL 컴포넌트의 경우에는 그냥 사용하면 됩니다.
(이 말은 Thread 각각이 생성해서 자신만 쓰고 delete하는 컴포넌트를 말합니다)
Synchronize를 쓰게 되면 Thread라기보다는 순차형으로 실행이 되기 때문에
쓰레드의 효과가 떨어진다고 생각이 됩니다.
그리고 다음은 참고입니다.
TListDemon::Button1Click(TObject *Sender)에서 보면
DoWork->Terminate()를 하고, Configuration을 한 다음에 다시 DoWork->Resume()을
합니다. 여기 문맥에서 보면 쓰레드 실행을 잠시 중단시키려고 하는 것 같은데
그렇다면 Terminate()가 아니라 Suspend()를 사용해야 합니다.
그리고, 또 TDowork::DistributeMail()에서 try랑 쌍을 이루는
아래의 내용이 있습니다.
catch (...)
{
delete query1, query2;
return;
}
delete query1, query2;
여기에서도 단지 query1, query2의 delete만 한다면
try/__finally를 이용하면 됩니다.
try {
} __finally {
delete query1, query2;
}
라고 하면 exception이 나건 안 나면 delete를 해주게 됩니다.
빌더소녀 님이 쓰신 글 :
: 쓰레드를 사용하는 프로그램을 만들었어요.
:
: 메일 서버가 작동되는 상황에서 메일링리스트를 구현하는 데몬인데..
:
: 실행되고 일을 잘하더니 한 1분 내로 프로그램을 끝내버려요.
:
: 도움말을 보고 함 만들어 보았는데 어떻게 된 건지 모르겟네요~ 오빠들 많이 도와주세요.
:
: 다음은 쓰레드 구현부 소스입니다.
:
: #include <vcl.h>
: #pragma hdrstop
:
: #include <DBTables.hpp>
:
: #include "Work.h"
: #pragma package(smart_init)
:
:
: __fastcall TDowork::TDowork(bool CreateSuspended)
: : TThread(CreateSuspended)
: {
: Priority = tpIdle;
: }
: //---------------------------------------------------------------------------
: void __fastcall TDowork::Execute()
: {
:
: while (!Terminated)
: {
: Synchronize(DistributeMail);
: }
: }
: //---------------------------------------------------------------------------
:
: void __fastcall TDowork::DistributeMail()
: {
: TQuery *query1, *query2;
:
: try
: {
: String Domain, List, Member, DomainPath, ListPath, MemberPath;
:
: query1 = new TQuery(Application); <----- 의심가는 부분1
: query2 = new TQuery(Application);
:
: query1->DatabaseName = "Neant";
: query2->DatabaseName = "Neant";
:
: query1->Close();
: query1->SQL->Clear();
: query1->SQL->Add("SELECT DOMAINNAME, LIST FROM LIST");
: query1->Open();
:
: while (!query1->Eof)
: {
: Domain = query1->FieldByName("DOMAINNAME")->AsString;
:
: List = query1->FieldByName("LIST")->AsString;
:
: TSearchRec neant;
:
: DomainPath = RootPath + "\\" + Domain;
:
: ListPath = DomainPath + "\\" + List + "\\" + "mailbox\\";
:
: int found = FindFirst(ListPath + "*.*", faAnyFile, neant);
:
: while (!found)
: {
: query2->Close();
: query2->SQL->Clear();
: query2->SQL->Add("SELECT MEMBER FROM MEMBER");
: query2->SQL->Add("WHERE DOMAINNAME = '" + Domain + "'");
: query2->SQL->Add("AND LIST = '" + List + "'");
: query2->Open();
:
: String SrcPath, DesPath;
:
: while (!query2->Eof)
: {
: Member = query2->FieldByName("MEMBER")->AsString;
:
: MemberPath = DomainPath + "\\" + Member + "\\mailbox\\";
:
: SrcPath = ListPath + neant.Name;
: DesPath = MemberPath + neant.Name;
:
: CopyFile(SrcPath.c_str(), DesPath.c_str(), false);
:
: query2->Next();
: }
:
: found = FindNext(neant);
: DeleteFile(SrcPath.c_str());
: }
:
: FindClose(neant);
: query1->Next();
: }
: }
: catch (...)
: {
: delete query1, query2;
: return;
: }
:
: delete query1, query2;
:
: }
:
: 쓰레드 클래스 소스 (헤더)
:
: class TDowork : public TThread
: {
: private:
: protected:
: void __fastcall Execute();
: public:
: String RootPath;
:
: void __fastcall DistributeMail();
:
: __fastcall TDowork(bool CreateSuspended);
: };
:
: 쓰레드를 부리는 메인 소스
:
: void __fastcall TListDemon::FormShow(TObject *Sender)
: {
: Dowork = new TDowork(true);
:
: Dowork->RootPath = ExtractFileDir(UserdbPath);
: Dowork->Resume();
: }
:
: // nMail 메일링 리스트를 관리 설정하는 폼을 생성하는 루틴
:
: void __fastcall TListDemon::Button1Click(TObject *Sender)
: {
: Dowork->Terminate();
:
: try
: {
: if (AreUsers())
: {
: Configuration = new TConfiguration(this);
: Configuration->ShowModal();
: }
: else
: {
: ShowMessage("nMail Server에 등록된 사용자가 없어요! ^0^n");
: }
: }
: __finally
: {
: Configuration->Free();
: }
:
: Dowork->Resume();
: }
:
: void __fastcall TListDemon::FormClose(TObject *Sender, TCloseAction &Action)
: {
: Dowork->Terminate();
: DeleteLocalAlias();
: Action = caFree;
: }
:
: 얘는 프로젝트 소스파일이에요
:
: WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
: {
: HANDLE Mutex;
:
: try
: {
: // 프로그램을 한번만 실행시킴. 두번째 인스턴스 생성방지...
:
: const char ProgMutex[] = "NEANT";
:
: if ( ( Mutex = OpenMutex(MUTEX_ALL_ACCESS, false, ProgMutex) ) == NULL )
: Mutex = CreateMutex(NULL, true, ProgMutex);
: else
: return 0;
:
: //nMail Server가 설치되어 있으면 리스트 데몬 활성화. 아니면 종료.
:
: if (IsnMailServer())
: {
: Application->Initialize();
: Application->CreateForm(__classid(TListDemon), &ListDemon);
: Application->Run();
: }
: else
: {
: String Alert;
: Alert = "이 Machine에 nMail 서버가 설치되지 않았네요~ ^0^n";
: MessageDlg(Alert.c_str(),mtConfirmation,TMsgDlgButtons() << mbOK, 0);
: Application->Terminate();
: }
: }
: catch (Exception &exception)
: {
: Application->ShowException(&exception);
: }
:
: ReleaseMutex(Mutex);
: return 0;
: }
:
: 참고로 운영체제는 윈도우 2000 어드밴스드 서버구여. 완벽하게 디버깅되어서 어떤 에러 어떤 경
:
: 고도 없어요 근데 왜 자동으로 프로그램이 끝나버릴까요 끝나기 전에도 일은 잘하구요. 매우 궁금
:
: 해요. 가르켜 주세요 *^0^*
:
: - 나의 사랑 에보니 -
:
:
:
|