Delphi 如何用多线程进行数据采集

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Delphi 如何用多线程进行数据采集相关的知识,希望对你有一定的参考价值。

参考技术A 就以下两个方面来讲解以下在delphi中如何用多线程进行数据采集:
---- 1. 多线程进行数据采集应解决的问题
---- 其实,多线程程序设计复杂是暂时的;如果,你采用传统的C进行多线程的设计,那么你必须自己控制线程间的同步。那将是很复杂的。但是,如果利用面向对象的设计方法,采用Delphi进行多线程程序设计,问题就简单多了。这是因为,Delphi已将多线程的复杂性替我们处理了,我们所要做的就是继承。
---- 具体地说,多线程数据采集需要完成以下工作:
---- ① 从TThread类派生一个自己的类SampleThread。这就是我们用于数据采集的类。进行采集时,只需要简单地创建一个SampleThread的实例。
---- ② 重载超类TThread的Execute方法。在这一方法中将具体地执行数据采集任务。
---- ③ 如果希望一边采集一边显示,就在编写几个用于显示采集进度的过程,供Execute方法调用。
---- TThread类中最常用的属性/方法如下:
Create方法:constructor Create
(CreateSuspended: Boolean);
---- 其中CreateSuspended参数确定线程在创建时是否立即执行。如果为True,新线程在创建后被挂起;如果为False,线程在创建后立即执行。
FreeOnTerminate属性:
property FreeOnTerminate: Boolean;
---- 该属性确定程序员是否负责撤消该线程。如果该属性为True,VCL将在该线程终止时自动撤消线程对象。它的缺省值为False。
OnTerminate属性:
property OnTerminate: TNotifyEvent;
---- 该属性指定一个当线程终止时发生的事件。
---- 下面看一个具体的例子:
---- 2. 多线程数据采集的实现
---- 这是笔者开发的一个测抽油机功图的程序。它的功能是采集抽油机悬点的载荷及位移数据,经过处理后做出抽油机的功图。图1(略)所示是数据采集时的界面。点“采集数据”按钮后,程序将创建一新的线程,并设置其属性。这一新线程将完成数据采集任务。程序如下:
Procedure TsampleForm.
DoSampleBtnClick(Sender: TObject);
Begin
ReDrawBtn.Enabled := True;
DoSampleBtn.Enabled := False;
FFTBtn.Enabled := True;
TheSampler := SampleThread.Create(False);
创建采集线程
TheSampler.OnTerminate := FFTBtnClick;
采集完成后要执行的任务
TheSampler.FreeOnTerminate := True;
采集完成后撤消
End;
---- 采集线程的类定义如下:
Type
SampleThread = class(TThread)
Public
function AdRead(ach: byte): integer; safecall;
读A/D卡的函数
procedure UpdateCaption;
显示采集所用时间
private
Private declarations
protected
thes, thep: real;
dt: real;
id: integer;
st, ed: LongInt;
procedure Execute; override;
这是关键。
End;
---- 在这个类中定义了一个函数AdRead用于操作A/D卡,两个过程用于显示采集的进度与所用时间。需要注意的是AdRead函数是用汇编写的,参数调用格式必须是safecall。
---- 关键的重载方法Execute的代码如下:
Procedure SampleThread.Execute;
Begin
StartTicker := GetTickCount;
id := 0;
Repeat
thes := Adread(15) * ad2mv * mv2l;
采集第15通道
thep := Adread(3) * ad2mv * mv2n;
采集第3通道
dt := GetTickCount - StartTicker;
sarray[id] := thes;
parray[id] := thep;
tarray[id] := dt;
inc(id);
Synchronize(UpdateCaption);
注意:显示采集进度
Until id >=4096;
ed := GetTickCount;
Synchronize(ShowCostTime);
注意:显示所用时间
end;
---- 从以上代码中可见,Execute与一般的代码并无本质区别。仅有的区别是显示采集进度和显示所用时间时,不能直接调用各自的过程,而是通过调用Synchronize间接地调用。这样作是为了保持进程间的同步。

socket如何用多线程实现同时能接收和发送消息

我先用伪代码写下我的想法
DWORD WINAPI ClientThreadRecv(LPVOID lpParameter)//写好接收消息线程

main()

ServerSocket = socket(AF_INET, SOCK_STREAM, 0)
设置struct sockaddr_in
bind()
listen()//监听
while(1)

accpet()//建立连接
send()
recv()//这里创建线程接收


这样写我运行还是没法实现同时接收和发送消息 只能发一条就必须等客户端回复才行 到底该如何写呀

单IP,多线程监听相同端口,不能实现,详见UNPV1,不过使用一个线程监听端口,把结果存入一个对象,然后多线程并发访问这个对象倒是可以实现的 参考技术A 把accept()提到while()外面,然后while()里面创建两个线程分别send和recv。
失误了,应该是主函数里只创建两个线程,while(1)放到线程里,send和recv放到while(1)里追问

刚才线程没放while里面 可放了后 由于大量循环创建线程导致线程创建全部失败

本回答被提问者采纳

以上是关于Delphi 如何用多线程进行数据采集的主要内容,如果未能解决你的问题,请参考以下文章

在delphi中如何用clientsocket进行实时发送。。即在数据库读取到数据就立即发送出去。。

Delphi中如何用IP地址的方式来连接Oracle数据库?

如何用多线程方式,提高rabbitmq消息处理效率?

delphi多线程怎么解决数据处理速度跟不上数据接收的速度?

看我如何用多线程,帮助运营小姐姐解决数据校对系统变慢!

请教如何用delphi5连接oracle数据库