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
[71320] Re:감사~ 질문 하나 더.. Re:Re:[질문] 종료 이벤트에서 Thread의 종료 지연 방법
장성호 [nasilso] 3555 읽음    2014-05-15 12:32

방법1

현재 방법에서..

Log쓰레드를 죽이지 마세요
MainThread가 죽을때  다른 백그라운드 쓰레드 모두 죽이고 죽습니다.
해제 안하면 자동으로 죽습니다.



또한 MainThread는 모든 리소스를 헤제한후에 죽으니까..
Application이나 Form과 같은 자원이 모두 해제된후에  죽습니다.


방법2.
   Projectxxx.cpp에서 다음과 같은 식으로 코딩해보세요

   Application->Run() ;
   delete MainForm;
   LogThread.StopAndFree;
  
방법3
   또다른 방법으로 프로그램에서 직접 Log를 파일에 저장하지 않고
   Log를 따로 저장하는 라이브러리나 프로그램을 만들어서 처리하는 방법이 있습니다.

   쓰레드에서 저장하는 방식이 아니구요..
    
그럼..


땅주인 님이 쓰신 글 :
: 감사합니다.
:
: 한가지만 더..
:
: 프로그램을 종료하면서 이런저런 Resource의 Release를 하면서,
: Socket /Serial Port들에 대한 Close 로그도 함께 저장하고 싶은데요..
:
: FormCloseQuery이벤트에서
: Socket / Serial Port를 Close하면 onDisconnect/onClose Event가 발생하고, 여기서 다시
: Log를 쓰게 되는데..
:
: 이미 Main Thread와 Log Thread는 Close 이벤트를 지나면서
: 종료가 되어서, 이 로그를 저장할 수 없는 상황인데요..
:
: 그래서, 이 이벤트 (Socket Close/Serial Port의 Close 이벤트)에 대한 로그를 모두 처리할 때까지
: Log 스레드와 프로그램의 종료를 지연하고 싶은데..
:
: 그냥 Sleep()으로 기다리는 것은 방법이 안되더군요..
:
: 어떤 방법이 있을 지?
:
:
: 장성호 님이 쓰신 글 :
: : 파일에 기록을 먼저 하고..
: : 화면에 표시는 메인폼이 있을때만 하면 되지 않나요?
: :
: : 대충 다음과 같이..
: :
: : //---------------------------------------------------------------------------
: : void TLogThread::LogWrite(STLogMessage *pLogMessage)
: : {
: :  
: :     //1) 파일기록을 먼저 하고..
: :     TDateTime t = pLogMessage->LogTime;
: :     USHORT iHour, iMinute, iSec, iMSec;
: :  
: :     t.DecodeTime(&iHour, &iMinute, &iSec, &iMSec);
: :  
: :     UnicodeString sLogMsg;
: :     sLogMsg = sLogMsg.sprintf(L"[%02d:%02d:%02d] ",iHour, iMinute, iSec);
: :     sLogMsg += pLogMessage->LogMessage;
: :   
: :     if ( pLogMessage->bFile ) {
: :         m_Log.LogMessage(sLogMsg);  // 로그 파일에 기록
: :     }
: : 
: :     //2) 어플이 실행중인 동안 화면에 표시 ... 
: :    if( Application->Terminated==false)
: :    {
: :         if ( FormMain->Memo->Lines->Count > 100 ) FormMain->Memo->Lines->Clear();
: :         FormMain->Memo->Lines->Insert(0, sLogMsg); // 메인 폼의 로그창에 기록
: :    }
: : }
: : 
: : 

: :
: : 그럼..
: :
: : 땅주인 님이 쓰신 글 :
: : : 환경: C++ Builder XE5
: : :
: : : 화면과 파일에 Log을 기록하는 LogThread를 운영중입니다.
: : : 잘 동작하는데, 프로그램 종료할 때 문제가 생기네요.
: : :
: : : 로그를 기록하는 것이 스레드로 빠져있으니
: : : 로그를 써야할 상황인데, MainForm이 먼저 종료되면서
: : : 로그가 기록되지 않는 증상이 발생하는데요..
: : :
: : : Form의 CloseQuery / Close 이벤트에서
: : : Socket을 닫거나 Serial Port를 닫으면서 해당 컴포넌트의 Close 이벤트가 다시 발생하고,
: : : 이 이벤트에 대한 로그를 로그 스레드에서 처리하는데, 벌써 메인 폼은 없어져서 
: : : 로그를 처리할 수 없는 상황이 생깁니다. 그냥 Sleep()으로 기다려도 MainThread가 Sleep()으로
: : : 빠져버리니 이것도 해결책이 되지 않더군요.
: : :
: : : 요지는 CloseQuery / Close 이벤트에서 LogThread가 자신의 로그 내용을 다 적을 때까지
: : : 기다려야 할 때 어떻게 하는 지..?
: : :
: : :
: : : //---------------------------------------------------------------------------
: : : // Close 관련 Event 
: : : //---------------------------------------------------------------------------
: : : 
: : : //---------------------------------------------------------------------------
: : : void __fastcall TFormMain::FormCloseQuery(TObject *Sender, bool &CanClose)
: : : {
: : : 	LogMessage("Software is closeing.....................................");
: : : 
: : : 	// Socket Release
: : : 	ASocket->Active   = false;	// Disconnect event 발생 => Log 기록
: : : 	BSocket->Active   = false;  // Disconnect event 발생 => Log 기록
: : : 
: : : 	// Serial Port Release
: : : 	SerialPort1->Open = false;  // Close Event 발생 => Log 기록
: : : 	SerialPort2->Open = false;  // Close Event 발생 => Log 기록
: : : 
: : : 	// Timer Stop
: : : 	// ....
: : : 
: : : 	// Other Resource Release
: : : 	// ....
: : : 
: : : 	// Message pumping
: : : 	//for ( int i = 0 ; i < 10 ; i++ ) {
: : : 	//	Application->ProcessMessages();
: : : 	//}
: : : 	CanClose = true;
: : : }
: : : 
: : : //---------------------------------------------------------------------------
: : : void __fastcall TFormMain::FormClose(TObject *Sender, TCloseAction &Action)
: : : {
: : : 	// Resource Release 
: : : 	
: : : 	delete pGLogSection;
: : : 	delete GLogQueue;
: : : 	delete GLogEvent;
: : : 
: : : 	Action = caFree;
: : : 	return;
: : : }
: : : 
: : : 
: : : //---------------------------------------------------------------------------
: : : // Log Thread Process 
: : : //---------------------------------------------------------------------------
: : : 
: : : //---------------------------------------------------------------------------
: : : void __fastcall TLogThread::Execute()
: : : {
: : : 	TWaitResult Result;
: : : 	STLogMessage *pLogMessage;
: : : 	while ( FormMain->m_bLogThread ) {
: : : 		Result = GLogEvent->WaitFor(EVENT_WAIT_TIME);	// wait 1 second
: : :         if ( Result == wrSignaled || Result == wrTimeout ) {
: : : 			while ( GLogQueue->Count() ) {
: : : 
: : : 				pGLogSection->Enter();
: : : 				pLogMessage = (STLogMessage *) GLogQueue->Pop();
: : : 				pGLogSection->Leave();
: : : 
: : : 				LogWrite(pLogMessage);
: : : 				delete pLogMessage;
: : :             }
: : : 		} else if ( Result == wrAbandoned ) {	// Event Object was destored
: : :         										// wrError: An error occured while waiting.
: : : 												// Check the LastError property for an error
: : :                                                 // code giving more informaiton.
: : :     	} else {
: : :         	// nothing to do..
: : :         }
: : :         //G_pSoundEvent->ResetEvent();			// Auto Event Reset mode
: : : 	}
: : : }
: : : 
: : : //---------------------------------------------------------------------------
: : : void TLogThread::LogWrite(STLogMessage *pLogMessage)
: : : {
: : : 	if ( FormMain->Memo->Lines->Count > 100 ) FormMain->Memo->Lines->Clear();
: : : 
: : : 	TDateTime t = pLogMessage->LogTime;
: : : 	USHORT iHour, iMinute, iSec, iMSec;
: : : 
: : : 	t.DecodeTime(&iHour, &iMinute, &iSec, &iMSec);
: : : 
: : : 	UnicodeString sLogMsg;
: : : 	sLogMsg = sLogMsg.sprintf(L"[%02d:%02d:%02d] ",iHour, iMinute, iSec);
: : : 	sLogMsg += pLogMessage->LogMessage;
: : : 
: : : 	FormMain->Memo->Lines->Insert(0, sLogMsg);	// 메인 폼의 로그창에 기록
: : : 
: : : 	if ( pLogMessage->bFile ) {
: : : 		m_Log.LogMessage(sLogMsg);	// 로그 파일에 기록
: : : 	}
: : : }
: : : 

: : :

+ -

관련 글 리스트
71312 [질문] 종료 이벤트에서 Thread의 종료 지연 방법 땅주인 3555 2014/05/14
71315     Re:[질문] 종료 이벤트에서 Thread의 종료 지연 방법 장성호 3560 2014/05/15
71319         감사~ 질문 하나 더.. Re:Re:[질문] 종료 이벤트에서 Thread의 종료 지연 방법 땅주인 3363 2014/05/15
71320             Re:감사~ 질문 하나 더.. Re:Re:[질문] 종료 이벤트에서 Thread의 종료 지연 방법 장성호 3555 2014/05/15
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.