帅
帅义庭
Unregistered / Unconfirmed
GUEST, unregistred user!
项目是这样的:计算机通过UDP协议接收数据包,每秒300个数据包,每个包长度固定为120字节,计算机需要对这些数据作实时运算处理,包括滤波,在屏幕上显示实时曲线,计算曲线的波峰波谷值,计数峰值的个数等等,还需要把这些计算的结果在曲线的相应位置标记出来.另外还有一下开关量采集开关量输出等任务.本人是这样的: 在主窗体中放置了一个Indy UDP控件接收数据包用来接收数据,接收的数据不作太多出来只是作了一个CRC校验, 然后就插入到一个公共数据包缓冲队列中mQuene, 本人又设计了一个数据处理线程,该线程是无限循环的专门从公共数据包缓冲队列mQuene中取得数据,然后运算,绘制曲线,并作标记图,最后还作开关量采集开关量输出工作.有关代码如下//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//// 接收UDP数据包 ////~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//procedure TfrmMain.UDPServerUDPRead(Sender: TObject;
AData: TStream;
ABinding: TIdSocketHandle);var sz:INTEGER;
rbuf:ARRAY[0..2048-1] of BYTE;
begin
AData.Read(rbuf,sz);
//读数据包 ExtractBC(@rbuf);
//从接收到的数据包中解析出各路波长值并存放到mbuf中 mQuene.InsertQuene( @mbuf[0],sizeof(mbuf) );
end;
//******************************************//* 线程构造函数 *//******************************************constructor CJZTHREAD.Create();
begin
inherited Create(FALSE);
//FALSE线程创建后处于运行状态 Piority:=tpNormal;
//tpTimeCritical,tpHighest,tpHigher,tpLower;
FreeOnTerminate:=True;
end;
//*********************************// 任务执行程序 *//*********************************Procedure CJZTHREAD.Execute;
begin
Repeat //Synchronize(DoTask);
do
Task();
//TApplication(self).processMessages();
until(Terminated);
end;
//*********************************// 任务执行程序 *//*********************************Procedure CJZTHREAD.DoTask();var i:INTEGER;
bRet:BOOLEAN;
nBuf:array[0..TOTAL_CHL*GRIDS_PER_CHL-1] of INTEGER;
begin
do
SIOTask();
//执行串口通信任务(向表示盘发送数据) do
IOTask();
//执行动态采集驱动任务 //循环读取队列中的所有数据并处理它 while(TRUE)do
begin
TRY EnterCriticalSection(FLock);
//进入临界区,阻止写 bRet:=mQuene.isEmpty;
FINALLY LeaveCriticalSection(FLock);
//读完成,离开临界区 end;
if(bRet) then
begin
EXIT;
//缓冲区中无数据 end;
TRY EnterCriticalSection(FLock);
//进入临界区,阻止写 mQuene.OutQuene( @nBuf[0],sizeof(nBuf) );
//从缓冲区中取出所有光栅数据并暂存到nBuf[]缓冲区中 FINALLY LeaveCriticalSection(FLock);
//读完成,离开临界区 end;
mJZTickCounter:=mJZTickCounter+1;
//每次解调器送来一个数据包该变量加1 begin
//@@@@@@@@@@@@@@@@@@@@@@@@@@对每路光栅数据(存放在nBuf[]中)滤波,滤波结果保存到mBuf[]中@@@@@@@@@@@@@@@@@@@@@@@@// for i:=0 to TOTAL_CHL*GRIDS_PER_CHL-1do
begin
{ //没有使用交流放大器 mBuf:=mGSFilter.GSOut(nBuf);
//高斯滤波 mBuf:=mFilter.fout1(mBuf);
//滑动滤波 } { //在实际现场运行 mBuf:=mGSFilter.GSOut(nBuf);
//高斯滤波 mBuf:=mACAmp.amp(mBuf);
//交流放大 mBuf:=mFilter.fout1(mBuf);
//滑动滤波 } //在实验室调试不需要滤波 mBuf:=mACAmp.amp(nBuf);
//交流放大 //mBuf:=nBuf;
//不滤波 mDyncBaseObj.TrackBase(mBuf);
//追踪动态基点,追踪的动态基点值保存在全局变量mBase中 end;
//@@@@@@@@@@@@@@@@@@@@@@@@@@对每路光栅数据(存放在nBuf[]中)滤波,滤波结果保存到mBuf[]中@@@@@@@@@@@@@@@@@@@@@@@@// if(mJZTickCounter<100) then
exit;
//确保滤波数据正确 (在实验室使用把该语句取消,在现场使用时需要使用该语句) //@@@@@@@@@@@@@@@@对每个滤波后的光栅数据(存放在mBuf[]中)加工去温度干扰,结果仍保存在mBuf[]中@@@@@@@@@@@@@@@@@@// for i:=0 to TOTAL_CHL*GRIDS_PER_CHL-1do
begin
mBuf:=mBuf-mBase;
//得到一个与温度无关的值 if(mBuf<CONST_BOTTOM_LINE) then
begin
mBuf:=CONST_BOTTOM_LINE;
//低于底线的部分截去 end else
begin
//if(mBuf>CONST_TOP_LINE) then
//begin
// mBuf:=CONST_TOP_LINE;
//高于顶线的部分截去 //end;
end;
end;
//@@@@@@@@@@@@@@@@对每个滤波后的光栅数据(存放在mBuf[]中)加工去温度干扰,结果仍保存在mBuf[]中@@@@@@@@@@@@@@@@@@// //@@@@@@@@@@@@@@@@@@@@@@@把滤波去温度干扰后的光栅数据(存放在mBuf[]中)进行分析计轴@@@@@@@@@@@@@@@@@@@@@@@@@@@@// {$IFDEF _MAS} //马鞍山 m27_29DGFsd.DoACP ( mBuf[01], mBuf[00] );
m27_29DGJsd1.DoACP( mBuf[20], mBuf[21] );
m27_29DGJsd2.DoACP( mBuf[10], mBuf[11] );
m27_29DGJsd3.DoACP( mBuf[31], mBuf[30] );
{$ENDIF} //马鞍山 {$IFDEF _JJP} //将军堡 //mXWGFsd.DoACP ( mBuf[00], mBuf[01] );
//mXWGJsd1.DoACP( mBuf[10], mBuf[11] );
//m1_3DGFsd.DoACP ( mBuf[10], mBuf[11] );
m1_3DGJsd1.DoACP( mBuf[20], mBuf[21] );
//m1_3DGJsd2.DoACP( mBuf[22], mBuf[23] );
//m1_3DGJsd3.DoACP( mBuf[30], mBuf[31] );
{$ENDIF} //将军堡 //@@@@@@@@@@@@@@@@@@@@@@@把滤波去温度干扰后的光栅数据(存放在mBuf[]中)进行分析计轴@@@@@@@@@@@@@@@@@@@@@@@@@@@@// end;
//@@@@@@@@@@@@@@@@@@@@@@@根据计轴点计轴数据计算区段情况@@@@@@@@@@@@@@@@@@@@@@@@@@@@// begin
{$IFDEF _MAS} //马鞍山 m27_29DG.DoSection();
{$ENDIF} //马鞍山 {$IFDEF _JJP} //将军堡 mXWG.DoSection();
m1_3DG.DoSection();
{$ENDIF} //将军堡 end;
//@@@@@@@@@@@@@@@@@@@@@@@根据计轴点计轴数据计算区段情况@@@@@@@@@@@@@@@@@@@@@@@@@@@@// mDataTool.DoIt();
//手动和自动存储数据 AppendDataToCurve();
//显示波形 //Sleep(1);
//线程挂起 end;
//end whileend;
请问我这样的的设计是否合理?我现在遇到的问题是,如果线程等级设置为tpNormal或者更底的等级时,则出现数据处理不过来,如果线程等级设置为tpHighter或者更高的等级时则出现主窗体界面冻结现象!请各位朋友给我提供高招!谢谢大家!
AData: TStream;
ABinding: TIdSocketHandle);var sz:INTEGER;
rbuf:ARRAY[0..2048-1] of BYTE;
begin
AData.Read(rbuf,sz);
//读数据包 ExtractBC(@rbuf);
//从接收到的数据包中解析出各路波长值并存放到mbuf中 mQuene.InsertQuene( @mbuf[0],sizeof(mbuf) );
end;
//******************************************//* 线程构造函数 *//******************************************constructor CJZTHREAD.Create();
begin
inherited Create(FALSE);
//FALSE线程创建后处于运行状态 Piority:=tpNormal;
//tpTimeCritical,tpHighest,tpHigher,tpLower;
FreeOnTerminate:=True;
end;
//*********************************// 任务执行程序 *//*********************************Procedure CJZTHREAD.Execute;
begin
Repeat //Synchronize(DoTask);
do
Task();
//TApplication(self).processMessages();
until(Terminated);
end;
//*********************************// 任务执行程序 *//*********************************Procedure CJZTHREAD.DoTask();var i:INTEGER;
bRet:BOOLEAN;
nBuf:array[0..TOTAL_CHL*GRIDS_PER_CHL-1] of INTEGER;
begin
do
SIOTask();
//执行串口通信任务(向表示盘发送数据) do
IOTask();
//执行动态采集驱动任务 //循环读取队列中的所有数据并处理它 while(TRUE)do
begin
TRY EnterCriticalSection(FLock);
//进入临界区,阻止写 bRet:=mQuene.isEmpty;
FINALLY LeaveCriticalSection(FLock);
//读完成,离开临界区 end;
if(bRet) then
begin
EXIT;
//缓冲区中无数据 end;
TRY EnterCriticalSection(FLock);
//进入临界区,阻止写 mQuene.OutQuene( @nBuf[0],sizeof(nBuf) );
//从缓冲区中取出所有光栅数据并暂存到nBuf[]缓冲区中 FINALLY LeaveCriticalSection(FLock);
//读完成,离开临界区 end;
mJZTickCounter:=mJZTickCounter+1;
//每次解调器送来一个数据包该变量加1 begin
//@@@@@@@@@@@@@@@@@@@@@@@@@@对每路光栅数据(存放在nBuf[]中)滤波,滤波结果保存到mBuf[]中@@@@@@@@@@@@@@@@@@@@@@@@// for i:=0 to TOTAL_CHL*GRIDS_PER_CHL-1do
begin
{ //没有使用交流放大器 mBuf:=mGSFilter.GSOut(nBuf);
//高斯滤波 mBuf:=mFilter.fout1(mBuf);
//滑动滤波 } { //在实际现场运行 mBuf:=mGSFilter.GSOut(nBuf);
//高斯滤波 mBuf:=mACAmp.amp(mBuf);
//交流放大 mBuf:=mFilter.fout1(mBuf);
//滑动滤波 } //在实验室调试不需要滤波 mBuf:=mACAmp.amp(nBuf);
//交流放大 //mBuf:=nBuf;
//不滤波 mDyncBaseObj.TrackBase(mBuf);
//追踪动态基点,追踪的动态基点值保存在全局变量mBase中 end;
//@@@@@@@@@@@@@@@@@@@@@@@@@@对每路光栅数据(存放在nBuf[]中)滤波,滤波结果保存到mBuf[]中@@@@@@@@@@@@@@@@@@@@@@@@// if(mJZTickCounter<100) then
exit;
//确保滤波数据正确 (在实验室使用把该语句取消,在现场使用时需要使用该语句) //@@@@@@@@@@@@@@@@对每个滤波后的光栅数据(存放在mBuf[]中)加工去温度干扰,结果仍保存在mBuf[]中@@@@@@@@@@@@@@@@@@// for i:=0 to TOTAL_CHL*GRIDS_PER_CHL-1do
begin
mBuf:=mBuf-mBase;
//得到一个与温度无关的值 if(mBuf<CONST_BOTTOM_LINE) then
begin
mBuf:=CONST_BOTTOM_LINE;
//低于底线的部分截去 end else
begin
//if(mBuf>CONST_TOP_LINE) then
//begin
// mBuf:=CONST_TOP_LINE;
//高于顶线的部分截去 //end;
end;
end;
//@@@@@@@@@@@@@@@@对每个滤波后的光栅数据(存放在mBuf[]中)加工去温度干扰,结果仍保存在mBuf[]中@@@@@@@@@@@@@@@@@@// //@@@@@@@@@@@@@@@@@@@@@@@把滤波去温度干扰后的光栅数据(存放在mBuf[]中)进行分析计轴@@@@@@@@@@@@@@@@@@@@@@@@@@@@// {$IFDEF _MAS} //马鞍山 m27_29DGFsd.DoACP ( mBuf[01], mBuf[00] );
m27_29DGJsd1.DoACP( mBuf[20], mBuf[21] );
m27_29DGJsd2.DoACP( mBuf[10], mBuf[11] );
m27_29DGJsd3.DoACP( mBuf[31], mBuf[30] );
{$ENDIF} //马鞍山 {$IFDEF _JJP} //将军堡 //mXWGFsd.DoACP ( mBuf[00], mBuf[01] );
//mXWGJsd1.DoACP( mBuf[10], mBuf[11] );
//m1_3DGFsd.DoACP ( mBuf[10], mBuf[11] );
m1_3DGJsd1.DoACP( mBuf[20], mBuf[21] );
//m1_3DGJsd2.DoACP( mBuf[22], mBuf[23] );
//m1_3DGJsd3.DoACP( mBuf[30], mBuf[31] );
{$ENDIF} //将军堡 //@@@@@@@@@@@@@@@@@@@@@@@把滤波去温度干扰后的光栅数据(存放在mBuf[]中)进行分析计轴@@@@@@@@@@@@@@@@@@@@@@@@@@@@// end;
//@@@@@@@@@@@@@@@@@@@@@@@根据计轴点计轴数据计算区段情况@@@@@@@@@@@@@@@@@@@@@@@@@@@@// begin
{$IFDEF _MAS} //马鞍山 m27_29DG.DoSection();
{$ENDIF} //马鞍山 {$IFDEF _JJP} //将军堡 mXWG.DoSection();
m1_3DG.DoSection();
{$ENDIF} //将军堡 end;
//@@@@@@@@@@@@@@@@@@@@@@@根据计轴点计轴数据计算区段情况@@@@@@@@@@@@@@@@@@@@@@@@@@@@// mDataTool.DoIt();
//手动和自动存储数据 AppendDataToCurve();
//显示波形 //Sleep(1);
//线程挂起 end;
//end whileend;
请问我这样的的设计是否合理?我现在遇到的问题是,如果线程等级设置为tpNormal或者更底的等级时,则出现数据处理不过来,如果线程等级设置为tpHighter或者更高的等级时则出现主窗体界面冻结现象!请各位朋友给我提供高招!谢谢大家!