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
[71319] 감사~ 질문 하나 더.. Re:Re:[질문] 종료 이벤트에서 Thread의 종료 지연 방법
땅주인 [heaven2] 3362 읽음    2014-05-15 11:19
감사합니다.

한가지만 더..

프로그램을 종료하면서 이런저런 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의 종료 지연 방법 장성호 3559 2014/05/15
71319         감사~ 질문 하나 더.. Re:Re:[질문] 종료 이벤트에서 Thread의 종료 지연 방법 땅주인 3362 2014/05/15
71320             Re:감사~ 질문 하나 더.. Re:Re:[질문] 종료 이벤트에서 Thread의 종료 지연 방법 장성호 3555 2014/05/15
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.