|
<<서문>>
저는 PLC에서 RS-232로 데이타를 읽어와서
1초에 한번꼴로 파라독스DB에 레코드를 생성하는
프로그램을 만들고 있습니다. 소위 이야기하는 MMI(Man-Machine-Interface)프로그램의
데이타 로깅(Logging)부분입니다.
통신모듈에 CPU TIme을 빼앗기면 안되기 때문에
통신관련Thread(이하 "■") 와 데이타로깅Thread(이하 "▲") 둘을 이용하고 있습니다.
앞에서 언급한 ■에 CPU TIme을 빼앗기면 안되기 때문에 Priority를 3~4로주고
▲에 0을 주었습니다.
<<본론>>
문제는 ▲에서 발생합니다.
- ■에서 TQueue로 TSmallIntArray로 정의된 배열 데이타가 계속 할당생성(New)되어서 Push됩니다.
- ▲에서 TQueue로부터 TSmallIntArray는 Pop되어 ParaDox DB 에Append 된뒤 delete됩니다.
문제점 ===> ▲에서 일정시간이 지나면(1시간 또는 2시간 특히 정한 시간이 없음)
PC가 SHotDown 됩니다.
- DB에 이상이 있을 수도 있을까봐 Personel Oracle를 쓰봐도 마찬가집니다.
- 제생각에 TSmallIntArray를 계속 New 하고 Delete하는 과정에서 Error가 나는 것이 아닐런지 ?????
원형Queue를 사용하면 메모리 할당을 계속 하지 않으면 괜챤을지..(아직 해보지 않아서)
어떻게 해야할지 모르겠습니다.
- DB상에 문제라면 TExt 파일로 저장해서 하루에 한번씩 batch로 DB에 넣어야 할까요...
이러면 문제가 많습니다.
- 해결해주시면 제가 한잔 사겠습니다. 창원에 내려 오시면...내려 오기전에 메일 주세요 꼭...
■------------------------------
....
통신 모듈
......
QueueAnalog->Push(AnalogSmallIntArray);
AnalogSmallIntArray = new TSmallIntArray(0,0);
if(QueueAnalog->Count() > 10){
if(!m_ExistThreadAnalogLogging){
ThreadAnalogLogging = new TThreadAnalogLogging(true); //Thread 만들어지지 않았다면 생성
m_ExistThreadAnalogLogging = true;
ThreadAnalogLogging->FreeOnTerminate =true; // Set FreeOnTerminate to true if you want to explicitly destroy threads after they finish executing.
ThreadAnalogLogging->Priority = StrToInt(ComboBoxThreadAnalog->Text);
}
if(ThreadAnalogLogging->Suspended){
ThreadAnalogLogging->Resume();
LabelMessage2->Caption = "ThreadAnalogLog Resume !" ;
}
}
▲----------------------------------
void __fastcall TThreadAnalogLogging::Execute()
{
int i=0;
AnsiString strTemp0="";
TSmallIntArray *AnalogSmallIntArray;
//---Thread 무한 루프----------------------------------------------------------------------------
TableAnalogLog->Open();
while(!Terminated)
{
if(QueueAnalog->Count() == 0)
{
LabelMessage2->Caption = "ThreadAnalogLog is Terminated!" ;
ThreadAnalogLogging->Terminate();//Thread0->Terminated = true로 됨
m_ExistThreadAnalogLogging = false;
continue;
}
if(QueueAnalog->Count() > 0)
{
AnalogSmallIntArray = (TSmallIntArray*)QueueAnalog->Pop();
//--- Disk Logging ------------------------------------------------------------------------
//향후에 PLC System 시간을 전송받아서 사용해야함.
TableAnalogLog->Append();
TableAnalogLog->FieldValues["AnalogDate"] = FormatDateTime("yyyy-mm-dd", Now());
strTemp0.printf("%02d:%02d:%02d:%03d",(int)AnalogSmallIntArray->GetItem(0),
(int)AnalogSmallIntArray->GetItem(1),
(int)AnalogSmallIntArray->GetItem(2),
(int)AnalogSmallIntArray->GetItem(3));
TableAnalogLog->FieldValues["AnalogTime"] = strTemp0;
TableAnalogLog->FieldValues["Analog0"] = (int)AnalogSmallIntArray->GetItem(0);
TableAnalogLog->FieldValues["Analog1"] = (int)AnalogSmallIntArray->GetItem(1);
TableAnalogLog->FieldValues["Analog2"] = (int)AnalogSmallIntArray->GetItem(2);
TableAnalogLog->FieldValues["Analog3"] = (int)AnalogSmallIntArray->GetItem(3);
TableAnalogLog->FieldValues["Analog4"] = (int)AnalogSmallIntArray->GetItem(4);
TableAnalogLog->FieldValues["Analog5"] = (int)AnalogSmallIntArray->GetItem(5);
TableAnalogLog->FieldValues["Analog6"] = (int)AnalogSmallIntArray->GetItem(6);
TableAnalogLog->FieldValues["Analog7"] = (int)AnalogSmallIntArray->GetItem(7);
TableAnalogLog->FieldValues["Analog8"] = (int)AnalogSmallIntArray->GetItem(8);
TableAnalogLog->FieldValues["Analog9"] = (int)AnalogSmallIntArray->GetItem(9);
try{ TableAnalogLog->Post(); }
catch(Exception &E)
{
LabelErrorMessage->Caption = "TableAnalogLog-->" + E.Message;
TableAnalogLog->Cancel();
}
delete AnalogSmallIntArray;
} //if(QueueAnalog->Count() > 0)
} //while((!Terminated)
TableAnalogLog->Close();
}
|