|
답변에 감사 드립니다.
근데 에러가 나거든요??
E2268 Call to undefined function 'Synchronize' 라고 에러가 납니다.
그리고 한가지 궁금한것 ..
fMain은 메인 폼이고 메인폼 또는 다른 폼에서 여러개의 스레드를 생성하는데
fMain의 멤버 변수에 저장하면 다른 스레드가 접근해서 데이타를 바꿀수 있을 거 같은데요..
그럼 원하는 로그값이 아니라 다른 로그값이 출력될 수도 있을 거 같은데요..
다시한번 답변 부탁드립니다.
넘초보 님이 쓰신 글 :
: 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(...)
: : {
: : ;
: : }
: : }
: : //---------------------------------------------------------------------------
|