delphi里怎样在线程里实时性高的处理大数据实时处理

Delphi&:&如何用多线程进行数据采集
就以下两个方面来讲解以下在delphi中如何用多线程进行数据采集:
---- 1. 多线程进行数据采集应解决的问题
其实,多线程程序设计复杂是暂时的;如果,你采用传统的C进行多线程的设计,那么你必须自己控制线程间的同步。那将是很复杂的。但是,如果利用面向对象的设计方法,采用Delphi进行多线程程序设计,问题就简单多了。这是因为,Delphi已将多线程的复杂性替我们处理了,我们所要做的就是继承。
---- 具体地说,多线程数据采集需要完成以下工作:
---- ①
从TThread类派生一个自己的类SampleThread。这就是我们用于数据采集的类。进行采集时,只需要简单地创建一个SampleThread的实例。
---- ② 重载超类TThread的Execute方法。在这一方法中将具体地执行数据采集任务。
---- ③ 如果希望一边采集一边显示,就在编写几个用于显示采集进度的过程,供Execute方法调用。
---- TThread类中最常用的属性/方法如下:
Create方法:constructor Create
(CreateSuspended: Boolean);
其中CreateSuspended参数确定线程在创建时是否立即执行。如果为True,新线程在创建后被挂起;如果为False,线程在创建后立即执行。
FreeOnTerminate属性:
property FreeOnTerminate: B
该属性确定程序员是否负责撤消该线程。如果该属性为True,VCL将在该线程终止时自动撤消线程对象。它的缺省值为False。
OnTerminate属性:
property OnTerminate: TNotifyE
---- 该属性指定一个当线程终止时发生的事件。
---- 下面看一个具体的例子:
---- 2. 多线程数据采集的实现
这是笔者开发的一个测抽油机功图的程序。它的功能是采集抽油机悬点的载荷及位移数据,经过处理后做出抽油机的功图。图1(略)所示是数据采集时的界面。点“采集数据”按钮后,程序将创建一新的线程,并设置其属性。这一新线程将完成数据采集任务。程序如下:
Procedure TsampleForm.
DoSampleBtnClick(Sender: TObject);
& ReDrawBtn.Enabled := T
& DoSampleBtn.Enabled := F
& FFTBtn.Enabled := T
& TheSampler := SampleThread.Create(False);
& 创建采集线程
& TheSampler.OnTerminate := FFTBtnC
& 采集完成后要执行的任务
& TheSampler.FreeOnTerminate := T
&& 采集完成后撤消
---- 采集线程的类定义如下:
& SampleThread = class(TThread)
function AdRead(ach: byte):
读A/D卡的函数
procedure UpdateC
显示采集所用时间
&&& { Private
declarations }
& protected
&&& thes, thep:
&&& st, ed:
procedure E
这是关键。
在这个类中定义了一个函数AdRead用于操作A/D卡,两个过程用于显示采集的进度与所用时间。需要注意的是AdRead函数是用汇编写的,参数调用格式必须是safecall。
---- 关键的重载方法Execute的代码如下:
Procedure SampleThread.E
& StartTicker := GetTickC
& id := 0;
thes := Adread(15) * ad2mv * mv2l;
采集第15通道
thep := Adread(3) * ad2mv * mv2n;
采集第3通道
GetTickCount - StartT
&&& sarray[id]
&&& parray[id]
&&& tarray[id]
Synchronize(UpdateCaption);
注意:显示采集进度
& Until id &=4096;
& ed := GetTickC
& Synchronize(ShowCostTime);
& 注意:显示所用时间
从以上代码中可见,Execute与一般的代码并无本质区别。仅有的区别是显示采集进度和显示所用时间时,不能直接调用各自的过程,而是通过调用Synchronize间接地调用。这样作是为了保持进程间的同步。
已投稿到:多线程查询数据库,偶尔会丢掉一个线程。但大部分时候是正常。苦恼中。该怎么处理 - Delphi当前位置:& &&&多线程查询数据库,偶尔会丢掉一个线程。但大部分时多线程查询数据库,偶尔会丢掉一个线程。但大部分时候是正常。苦恼中。该怎么处理&&网友分享于:&&浏览:38次多线程查询数据库,偶尔会丢掉一个线程。但大部分时候是正常。苦恼中。如题。使用多个线程查询数据,然后汇总为1个数据集。偶尔会丢掉一个线程查询的数据集。可能是什么原因呢。代码很长,熟悉多线程的兄弟提示下,我贴相关的代码出来。丢掉线程后,下次查询会出来如下错误。'Access violation at address 770F4C27 in module 'oleaut32.dll'没有丢掉线程时,无此错误提示。一共就5个线程而已。确实是很奇怪的问题。我已经仔细检查了数据集,在少数情况(大概十几次中出现1次)有1个线程的数据集丢失。所有代码如下=====线程的代码==================unit QueryTinterface &
ActiveX;const &
WM_QueryDone
WM_User+1010;type &
TQueryThread
class(TThread) &
CreateSQL(const
protected &
constructor
Create(const
ADataSetProvider:
THandle); & &
& implementationuses
TQueryThread
& constructor
TQueryThread.Create(const
ADataSetProvider:
TDataSetP &
TADOQuery.Create(nil); &
FQuery.ConnectionString
' Provider=SQLOLEDB.1;Password=111;Persist Security Info=TUser ID=Initial Catalog=test';
//写入链接串 &
FQuery.SQL.Text
CreateSQL(FTag);
//创建SQL语句 &
ADataSetProvider.DataSet
FreeOnTerminate
Create(False);function
TQueryThread.CreateSQL(const
TTag):begin &
'select top 5 * from VW_test where rq= '' 00:00:00.000''';
'select top 5 * from VW_test where rq= '' 00:00:00.000'''; &
'select top 5 * from VW_test where rq= '' 00:00:00.000''';
'select top 5 * from VW_test where rq= '' 00:00:00.000''';
'select top 5 * from VW_test where rq= '' 00:00:00.000'''; &
&procedure
TQueryThread.Ebegin &
CoInitialize(nil); &
FQuery.O &
PostMessage(FHandle,
WM_QueryDone,
//发送查询结束消息 &
CoUnI &end.===========================调试的代码==unit Unit1;interfaceuses & Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, & Dialogs, StdCtrls, Buttons, DB, DBClient, Grids, DBGrids, Provider, & QueryThread,ADODB,Ctype & TMainForm = class(TForm) &
BRefresh: TBitB &
CDSLocal: TClientDataS &
CDSRemote_2: TClientDataS &
CDSRemote_1: TClientDataS &
CDSRemote_3: TClientDataS &
CDSRemote_4: TClientDataS &
DSPLocal: TDataSetP &
DSPRemote_1: TDataSetP &
DSPRemote_2: TDataSetP &
DSPRemote_3: TDataSetP &
DSPRemote_4: TDataSetP &
DSLocal: TDataS &
DBGridLocal: TDBG &
ADOConnection1: TADOC &
BtnOneThread: TBitB &
DS_OneThread: TDataS &
CDS_OneThread: TClientDataS 共&3&页:
12345678910
12345678910
12345678910 上一篇:下一篇:文章评论相关解决方案 12345678910 Copyright & &&版权所有delphi.thread.线程循环执行体结构 - 推酷
delphi.thread.线程循环执行体结构
线程话题太大,又都是些坑,不知从哪方面讲起,所以,想一出是一出了。
不管怎样,我们从开始使用D,不管有没有用线程,其实它已经帮我们做了一个最完整的线程执行处理:Application.Run.
这行App.Run,在dpr,想来各位都经常能够看到,如果跟踪下去,我们就会发现,它其实就是一个最完整的线程执行体的结构了:
 我将里面一些代码删除掉了,再将HandleMessage的代码复制过来,然后,代码如下:
procedure TApplication.R
if not ProcessMessage(Msg) then Idle(Msg);
HandleException(Self);
好了,我们不用去看里面代码意思,因为从代码意思来讲,它思路很简单,而且此文,也不是要去分析介绍App的代码。
这个Run,其实给我们介绍了一个线程执行体的大体结构思路,我觉得有意思的就是这循环体结构了。
上述的APP循环执行体,大体思路是:
1: 调用消息处理();
2:&没消息,就做空闲处理();
3: 不中断程序就继续循环。
这循环结构,我觉得与线程操作大体思路是相符的。那么,它也是可以看成是线程循环执行结构了:
procedure TMyThread.Execute();
if not DoThreadJob() and not DoThreadIdle() then
Sleep(10);
on E: Exception do
DoHandleException(E);
当然,未有作业时,Sleep进行阻塞及切换线程时,可以弄个计数,累计idle的次数,到了一定次数后,再进行sleep,计数再复位。
如下示例:
procedure TMyThread.Execute();
// 根据线程服务性质,进行设定,或进行外部配置
// MAX_IDLE值越大,表示该线程的处理需要越多时间(切换次数越少),
// MAX_IDLE值越小,线程切换次数越多。
MAX_IDLE = 32;
idle_count: I
idle_count := 0;
if not DoThreadJob() then
if not DoThreadIdle() then
Inc(idle_count)
idle_count := 0;
idle_count := 0;
if idle_count &= MAX_IDLE then
idle_count := 0;
Sleep(10);
on E: Exception do
DoHandleException(E);
然后,线程在未有作业处理时,去做空闲处理,空闲处理也未有时,再sleep,我觉得这思路,在写长期运行的逻辑服务处理是很好的适用思路。
且很多处理,是可以放置于ThreadIdle进行外部处理,再扩展,如同Application.Idle,运行频率是非常高。。。
好像要写的东西,就这么些。。。
水平有限,如有雷同,就是盗链,:D
已发表评论数()
已收藏到推刊!
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
没有分页内容
图片无法显示
视频无法显示
与原文不一致上面所给出的第一种解决方案:
  线程(Execute)在执行定时循环;然后先让 DestroyAThread设置 Terminated属性,通知线程去结束执行、释放资源;然后在线程结束执行、释放资源之后再去通知DestroyAThread,再由DestroyAThread来显式调用线程的 Free方法来释放线程
所以结合 FreeOnTerminate的作用,复习一下:
  类 Create 了就要 F&
  但 TThread(的子类) 有特殊性,&很多时候我们不能确定新建的线程什么时候执行完(也就是什么时候该释放);&  
  如果线程执行完毕自己知道释放就好了, 所以 TThread 给了一个布尔属性 FreeOnTerminate, 如果为 True, 线程执行完毕后就会自释放.
进行改造:
  首先在线程的Execute方法里面将 FreeOnTerminate设置为True,然后进行自己的定时循环执行;然后DestroyAThread设置Terminated属性,通知线程去结束执行、释放资源;然后在线程结束执行、释放资源之后,因为FreeOnTerminate设置为True了,所以就不要再通知 DestroyAThread,自己在释放完资源、结束执行之后,就会自释放。
  同样DestroyAThread设置Terminated属性之后,就可以直接退出,因为不需要在DestroyAThread里面显式释放线程。
  同样也就不需要线程再有 CanFree这种通知别人来释放它的属性了,所以也能简化线程类的设计(在面向对象的程序设计中一个原则就是:类尽可能小,所以那些能不需要的属性、方法就不要去定义和使用,把冗余的属性和方法一定要去掉&&)
所以新的代码可以是这样的
Execute方法:
procedure&TDoSomeThingThread.E
&&i:&Integer;
&&inherited;
&&FreeOnTerminate:=&True;
&&&&while&not&Self.Terminated&do
&&&&&&........
&&&&&&........
&&&&&&Sleep(5);
&&&&&&Application.ProcessM
DestroyAThread方法:
procedure&DestroyAThread(testThread: TDoSomeThingThread);
&&itime:&Cardinal;
&&if&Assigned(testThread)&then
&&&&testThread.T&&&&&&
&&end;&&&&
/xumenger/p/4454115.html
Views(...) Comments()线程中同步方法不能带参数的解决方法
Synchronize的函數是沒有參數的,
可以你可以透過定義在Thread中的成員, 來傳遞參數
TMyThread = class(TThread)
FSyncParam1:
procedure SyncM
procedure E
implementation
procedure TMyThread.E
FSyncParam1 := 1;
Synchronize(SyncMethod);
FSyncParam1 := 2;
Synchronize(SyncMethod);
procedure TMyThread.SyncM
case FSyncParam1 of
delphi目录下有个/demo/thread
的demo,里面有vcl对象在现程中的使用.跟楼上讲的差不多,
对于要传送的参数定义为线程类的私有变量,然后写个不带参数的syncmethod,
具体参数参考全局私有变量,然后sycnronize(syncmethod)
Delphi教程:
Delphi控件:}

我要回帖

更多关于 storm实时数据处理pdf 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信