|
if(fMain->reLog->Lines->Count > 1000) fMain->reLog->Clear();
fMain->reLog->SelStart = 0;
fMain->reLog->SelAttributes->Color = Color;
fMain->reLog->Lines->Insert(0,sMemo);
위 부분에 Synchronize 를 적용하면 되겠네요.
sMemo = sDateTime+" "+sMemo;
m_sMemo = sMemo; // 멤버변수에 갖고 있자.
Synchronize(WLog)
void __fastcall TfMain::WLog()
{
if(fMain->reLog->Lines->Count > 1000) fMain->reLog->Clear();
fMain->reLog->SelStart = 0;
fMain->reLog->SelAttributes->Color = Color;
fMain->reLog->Lines->Insert(0, m_sMemo); // 멤버변수에 저장된 내용.
}
hann1004 님이 쓰신 글 :
: 제가 지금 만들고 있는 프로그램이 멀티 스레드 프로그램인데요..
: 100개이상의 스레드를 한꺼번에 실행시키거든요??
: 근데 메인폼에 스레드의 로그를 표출하기 위해 richedit 박스를 올려놓고 스레드 생성시 또는 이벤트 발생시 richedit박스에 표출해주고 있는데...
: 테스트용으로 1개의 스레드를 가지고 테스트 했을 때는 전혀 문제가 없거든요??
: 근데 여러개를 띠웠을때는
: Project COMM.exe raised exeption class EOutOfResources with message 'RichEdit Line Insertion error' 라고 발생하네요.....
: 표출해주는 함수에 인자가 있어서 synchronize를 사용하면 될거 같은데... 함수에 인자가 있어서 불가능할거 같구..
: 혹시 경험해 보신분이나 잘 알고 계신 고수분들 도움 요청드립니다.
: 참고로 os는 2000 인데요... 2003 서버에서 사용할거구요..
: 소스는 길어서 전체를 올릴수 없는데..
: 스레드 생성하는 부분과 로그 함수를 올립니다.
: 고수분들 도와 주십시요
:
: ///////////////스레드에서 다른 스레드 생성하는 부분////////////////////
: fMain->WriteLog(Global->m_WinName,"TPipeCreateThread.cpp","Execute",m_sThreadInfo+"TPipeCreateThread-이벤트 ",ELSE);
:
: FreeOnTerminate = true;
: //---- Place thread code here ----
: while(!Terminated){
: switch(m_nDivision){
: case SERVER_CREATE: //Write Read용으로 Instance를 2개 실행시킴.
: //WaitForSingleObject(m_hCreateEvent,INFINITE);
: fMain->WriteLog(Global->m_WinName,"TPipeCreateThread.cpp","Execute",m_sThreadInfo+"TPipeCreateThread-서버용 파이프",NORMAL);
: dwReturn = WaitForMultipleObjects(2,a_hEvents,false,INFINITE);
: dwEvent = dwReturn - WAIT_OBJECT_0;
: if(dwEvent == 0){
: fMain->WriteLog(Global->m_WinName,"TPipeCreateThread.cpp","Execute",m_sThreadInfo+"TPipeCreateThread-파이프 생성",ELSE);
: a_hPipe=CreateNamedPipe(m_sPipeName.c_str(),
: PIPE_ACCESS_DUPLEX,PIPE_TYPE_MESSAGE,//PIPE_TYPE_BYTE,
: 2,MAX_PIPE_DATA_SIZE,MAX_PIPE_DATA_SIZE,10000,NULL);
: a_bCon=ConnectNamedPipe(a_hPipe,NULL);
: if((a_bCon==false) && (GetLastError() == ERROR_PIPE_CONNECTED)) a_bCon=true;
: if(a_bCon==true){
: Sleep(10);
: fMain->WriteLog(Global->m_WinName,"TPipeCreateThread.cpp","Execute",m_sThreadInfo+"TPipeCreateThread-파이프상태체크",ELSE);
: GetNamedPipeHandleState(a_hPipe,NULL,&(a_pPipeInfo->dwInstance),NULL,NULL,NULL,0);
: a_pPipeInfo->hPipe = a_hPipe;
: a_pPipeInfo->nDivision = SERVER_CREATE_PIPE;
: a_pPipeInfo->nVMS = m_nVMS;
: fMain->WriteLog(Global->m_WinName,"TPipeCreateThread.cpp","Execute",m_sThreadInfo+"TPipeCreateThread-포스트메시지 전송",DETAIL);
: PostMessage(m_hWnd,UM_PIPE_CONNECTION_SUCCESS,(WPARAM)a_hPipe,(LPARAM)a_pPipeInfo);
: }
: else CloseHandle(a_hPipe);
: }
: break;
: case CLIENT_CONNECTION:
: fMain->WriteLog(Global->m_WinName,"TPipeCreateThread.cpp","Execute",m_sThreadInfo+"TPipeCreateThread-클라이언트용파이프",ELSE);
: //WaitForSingleObject(m_hCreateEvent,INFINITE);
: dwReturn = WaitForMultipleObjects(2,a_hEvents,false,INFINITE);
: fMain->WriteLog(Global->m_WinName,"TPipeCreateThread.cpp","Execute",m_sThreadInfo+"TPipeCreateThread-파이프 생성",ELSE);
: dwEvent = dwReturn - WAIT_OBJECT_0;
: if(dwEvent == 0){
: do{
: a_bCon=WaitNamedPipe(m_sPipeName.c_str(),10000);
: if(a_bCon){
: a_hPipe=CreateFile(m_sPipeName.c_str(),GENERIC_READ | GENERIC_WRITE,
: 0,NULL,OPEN_EXISTING,0,NULL);
: if(a_hPipe!=INVALID_HANDLE_VALUE){
: fMain->WriteLog(Global->m_WinName,"TPipeCreateThread.cpp","Execute",m_sThreadInfo+"TPipeCreateThread-파이프 상태체크",ELSE);
: GetNamedPipeHandleState(a_hPipe,NULL,&(a_pPipeInfo->dwInstance),NULL,NULL,NULL,0);
: a_pPipeInfo->hPipe = a_hPipe;
: a_pPipeInfo->nDivision = CLIENT_CONNECTION_PIPE;
: a_pPipeInfo->nVMS = m_nVMS;
: fMain->WriteLog(Global->m_WinName,"TPipeCreateThread.cpp","Execute",m_sThreadInfo+"TPipeCreateThread- 포스트메시지 전송",DETAIL);
: PostMessage(m_hWnd,UM_PIPE_CONNECTION_SUCCESS,(WPARAM)a_hPipe,(LPARAM)a_pPipeInfo);
: }
: }
: Sleep(100);
: }while(!a_bCon);
: }
: break;
: }
: }
:
:
: //////////////////////////////스레드 생성자///////////////////////////////////////
: __fastcall TPipeReadThread::TPipeReadThread(HANDLE hPipe,
: int nVMS,
: HANDLE hWnd,
: HANDLE hReadEvent,
: int nFlag)
: : TThread(true)
: {
: m_hPipe = hPipe;
: m_nVMS = nVMS;
: m_hWnd = hWnd;
: m_hReadEvent = hReadEvent;
: m_nFlag = nFlag;
: if(m_nFlag == VMSINTERFACE) m_sEXEName = "VMSINTERFACE";
: else m_sEXEName = "VMSCOMM";
: m_sThreadInfo = nVMS ;//+ "-" + hPipe;
: Priority = tpNormal;
: fMain->WriteLog(Global->m_WinName,"TPipeReadThread.cpp","TPipeReadThread",m_sThreadInfo+"스레드 생성완료",DETAIL);
: Resume();
:
:
: }
: ////////////////////////////로그작성함수////////////////////////////////////////
: 각각의 Level에 따라서 표출색을 달리하고 Level에 따라 파일또는 화면에 호출하는 함수입니다.
: 위의 두부분에 서 보시면 fMain->WriteLog라고 되어있는 부분이 모두 로그를 표출하는 부분입니다.
:
: void __fastcall TfMain::WriteLog(AnsiString sExeName, AnsiString sSource, AnsiString sFunction, AnsiString sMemo,int Level)
: {
: //표출로그
:
: try{
: if(Level <= cboView->ItemIndex){
: TColor Color;
: switch(Level){
: case ALERT : //alert --
: Color = clRed;
: break;
: case WARN : //warn
: Color = clBlue;
: break;
: case NORMAL : //normal
: Color = clFuchsia;
: break;
: case DETAIL : //detail
: Color = clBlack;
: break;
: }
: String sDateTime = FormatDateTime("[YYYY/MM/DD, TT]",Now());
:
: sMemo = sDateTime+" "+sMemo;
:
: if(fMain->reLog->Lines->Count > 1000) fMain->reLog->Clear();
: fMain->reLog->SelStart = 0;
: fMain->reLog->SelAttributes->Color = Color;
: fMain->reLog->Lines->Insert(0,sMemo);
: }
: }catch(...){
: ;
: }
:
: try{
: if(Level <= fMain->cboSave->ItemIndex){
: if(Global->m_Options.LOG.bFileLogging){
: String a_sDate = FormatDateTime("YYYYMMDD", Now());
: String a_sTime = FormatDateTime("<HH:NN:SS> ", Now());
: String a_sFileName, a_sTmp;
: TFileStream *a_FileStream;
: const WORD OPENMODE = fmOpenReadWrite | fmShareCompat | fmShareDenyNone;
:
: a_sFileName = LOG_PATH+sExeName;
: if (!DirectoryExists(a_sFileName))
: {
: if (!CreateDir(a_sFileName))
: throw Exception("Cannot create \\"+sExeName);
: }
:
: a_sFileName += "\\"+a_sDate+".log";
: if(!FileExists(a_sFileName)) FileClose(FileCreate(a_sFileName));
: a_FileStream = new TFileStream(a_sFileName,OPENMODE);
: a_FileStream->Seek(0, soFromEnd);
:
: a_sTmp = a_sTime+sSource+"/"+sFunction+":"+sMemo;
: a_FileStream->Write(a_sTmp.c_str(), a_sTmp.Length());
: a_FileStream->Write("\r\n", 2);
: delete a_FileStream;
: a_FileStream = NULL;
: }
: }
: }catch(...)
: {
: ;
: }
: }
: //---------------------------------------------------------------------------
|