现在手头有个项目,需要对数据进行采集处理存储数据采集需要对8个com口进行监听,每个com口最多一秒有5组数据到达,每组数据不超过15字节。在每组数据到达后需要调用一个函数对数据进行处理,处理后需要将其存放在数据库中,数据库可能为远程数据库,连接带宽低于1M现在准备利用多个线程扫描各个com口,大概是建立8个线程一个监听一个线程
有数据到达后积进行处理(调用函数),然后存盘
线程是利用VB的TMSCOMM控件进行控制(还没有试过不知道能不能使用)由于TMSCMM有事件 可以得知数据的到达,到达后即进行数据处理
但是考虑到数据量比较多,按程序流程,可能会出现正在处理数据时就有新的数据到达com口,或者正在更新数据库时有数据到达的问题,这样可能漏掉重要的数据用各个线程扫描各端口应该是没有问题吧,主要是在接下来的对数据处理存储时这样处理行不行啊,怎么样处理 数据处理存储 这一块?
希望各位给些意见,谢谢
有数据到达后积进行处理(调用函数),然后存盘
线程是利用VB的TMSCOMM控件进行控制(还没有试过不知道能不能使用)由于TMSCMM有事件 可以得知数据的到达,到达后即进行数据处理
但是考虑到数据量比较多,按程序流程,可能会出现正在处理数据时就有新的数据到达com口,或者正在更新数据库时有数据到达的问题,这样可能漏掉重要的数据用各个线程扫描各端口应该是没有问题吧,主要是在接下来的对数据处理存储时这样处理行不行啊,怎么样处理 数据处理存储 这一块?
希望各位给些意见,谢谢
你的情况,没有问题的,新数据会放在缓冲区,知道你下次去取!!
>>线程是利用VB的TMSCOMM控件进行控制(还没有试过不知道能不能使用)
没有问题的, Mscomm很稳定!!对你说的情况,我认为实现不难!!
以下是从一个实际应用的线程中摘录出来的处理,在此线程中,可以同时读取32路串口。implementationConst MaxComPort=8; //定义8个Com端口
MaxComBufLen=100; //每个端口最多接收100字节Type ComBuf = Packed Record
Dat: Array[1..MaxComBufLen] of Byte;
End;procedure RecvComThread_Execute;Var hComPort: Array[0..MaxComPort-1] of THandle;
RecvBufs: Array[0..MaxComPort-1] of ComBuf;
RecvEvents: Array[0..MaxComPort-1] of THandle;
RecvOverLap: Array[0..MaxComPort-1] of TOverLapped;
RecvBytes: Array[0..MaxComPort-1] of Dword;Var Len: Word;
ks: Word;
WaitNo: Dword;
PortNo: Byte;
S1: String;
ComOk: Boolean;
begin ZeroMemory(@RecvBufs,SizeOf(RecvBufs));
ZeroMemory(@RecvEvents,SizeOf(RecvEvents));
ZeroMemory(@RecvOverLap,SizeOf(RecvOverLap)); For ks:=0 To MaxComPort-1 Do
Begin
hComPort[ks]:=CreateFile(PChar('\\.\'+ComName[ks]),
GENERIC_READ or GENERIC_WRITE,
0,Nil,OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL or FILE_FLAG_OVERLAPPED,0);
If (hComPort[ks]>0) Then { 记录Port ks 打开成功}
End; ThisThreadRun:={若所有端口打开成功,则为True}; For ks:=0 To MaxComPort-1 Do //为每个端口创建一个事件
Begin
RecvEvents[ks]:=CreateEvent(Nil,False,False,Nil);
RecvOverLap[ks].hEvent:=RecvEvents[ks];
End;
For ks:=0 To MaxComPort-1 Do //启动各个端口的异步读操作
Begin
ReadFile(hComPort[ks],RecvBufs[ks],SizeOf(RecvBufs[ks]),
RecvBytes[ks],@RecvOverLap[ks]);
End; While ThisThreadRun Do
Begin
WaitNo:=WaitForMultipleObjects(MaxComPort,@RecvEvents,False,INFINITE);
If (WaitNo>=0) And (WaitNo<MaxComPort) Then
Begin
PortNo:=WaitNo;
If GetOverLappedResult(hComPort[PortNo],RecvOverLap[PortNo],
RecvBytes[PortNo],False) Then
Begin
Len:=RecvBytes[PortNo]; //在第PortNo端口读出Len字节
//如果为字节中断则只能读出一个字节;
//如果串口为只能,用特殊字符中断,则可以
//一次读多个字节 {处理第PortNo端口的数据} ReadFile(hComPort[PortNo], //继续启动异步读取PortNo端口
RecvBufs[PortNo],
SizeOf(RecvBufs[PortNo]),
RecvBytes[PortNo],
@RecvOverLap[PortNo]); End;
End;
End;
EndThread(0);
end;initializationend.
谢谢各位的帮助
to Seahilly(小峰)
有空学些学习你的程序