delphi线程

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了delphi线程相关的知识,希望对你有一定的参考价值。

Type
TADOThread=class(TThread)
procedure Execute(AdoConn:tadoconnection;Adoquery:Tadoquery;SQLString:string);
destructor Destroy;
end;
implementation

$R *.dfm

procedure TADOThread.Execute(AdoConn:tadoconnection;Adoquery:Tadoquery;SQLString:string);
begin
CoInitialize(nil);
adoquery.Connection:=adoconn;
adoconn.LoginPrompt:=false;
adoquery.SQL.Text:=sqlstring;
if pos('select',sqlstring)=0 then
adoquery.ExecSQL
else
adoquery.Open;
end;
destructor TADOThread.Destroy;
begin
couninitialize;
end;
请问这个线程有什么问题,测试过可以通过,但并不能体现线程的优点。
softwb说我这里只有一个主线程,因为是刚学,,而且还是自学。所以有很多不懂的地方。
我主要是想通过ADO实现多线程查询数据,解决因为数据量太大而做一个查询要等待过长的时间。

你使用线程类有问题:
procedure Execute(AdoConn:tadoconnection;Adoquery:Tadoquery;SQLString:string);

Execute不用参数,直接在后边override;就可以了.是覆盖方法

想动态生成ADO的话.可以构造一个函数.在Create构造函数中动态创建
在Destroy析构函数中释放ADO

在Execute中是执行的代码,中间如果是操作VCL或全局变量的话.要注意同步!

还有.1楼说的有问题.

你使用的是线程类创建,是一个线程.

跟主线程无关.!在线程中使用synchronize,才会将线程加入到主线程中运行.

在补充一下

你可能将ADO组件加入到了窗体中,这样,把ADO组件加入到线程的构造函数中就

可以在线程中直接使用了!

百度一下.线程类使用方法,了解系统线程与进程的结构就明白了!

再补充一点"分太少了.哎~~"
参考技术A 你要先提出问题,而不是我们帮你找问题。

线程是很有用的,比较调用一个外部程序,但想实现把外部程序关闭后才允许操作主窗口,这时用线程很容易实现这种效果。

所以一切是看你想要解决什么问题,而不是盲目使用。
参考技术B 线程优点是多线程一起运行就是优点
比如一个线程执行初始化程序,另一个线程计算用户数,再另一个线程又做其它事。你就一个主线程当然看不出优点

转:学习笔记:delphi多线程学识

学习笔记:delphi多线程知识
最近一直在温习旧的知识,刚好学习了一下Java的线程安全方面的知识,今天想起之前一直做的Delphi开发,所以还是有必要温习一下,看看这些不同的编程语言有什么不同之处。
 
Delphi的线程同步方法:
1、临界区
申明一个临界资源
FLock   : TRTLCriticalSection;
先初化一个临界资源对象
InitializeCriticalSection(FLock)
销毁临界资源对象
DeleteCriticalSection(FLock)
procedure TSaveThread.PushTask(pTask: pFileInfo);
begin
  //进入临界资源,有线程占用后,后面的线程会阻塞
  EnterCriticalSection(FLock);
  try
    //这里是受保护的代码
    if not Assigned(FTasks) then
      FTasks:= TList.Create;

    FTasks.Add(pTask);
  finally
    //离开临界资源,其他的阻塞的线程可以进入
    LeaveCriticalSection(FLock);
  end;
end;
这种方式还是挺简单的,和Java中的synchronized代码块方式类似
2、Event事件
Event有两种状态:有信号和无信号,通过这个特性可以用于线程同步。Event相关的API也多,控制起来也比较灵活,看看他的几个方法:
CreateEvent:创建事件
SetEvent:设置为有信号状态
ResetEvent: 设置为无信号状态
PulseEvent :设置为有信号状态,接着又设置为无信号状态(有点类似于单步调试的感觉)
在线程中还是要用WaitForSingleObject来阻塞
procedure TSearchTopNThread.Execute;
begin
  while not Self.Terminated do
  begin
    WaitForSingleObject(FEvent, INFINITE);//FEvent为无信号时阻塞,直到变为有信号时代码继续执行
    .......
  end;
end;
//设置事件状态为无信号,阻塞线程
procedure TForm1.Button1Click(Sender: TObject);
begin
  ResetEvent(hEvent);
end;

//设置事件状态为有信号,线程解除阻塞
procedure TForm1.Button2Click(Sender: TObject);
begin
  SetEvent(hEvent);
end;

//设置一次脉冲信号状态,先设置有信号,再设置无信号
procedure TForm1.Button3Click(Sender: TObject);
begin
  PulseEvent(hEvent);
end;
 
 
3、互斥对象
var  hMutex: THandle; //互斥对象的句柄

function ThreadFun(p: Pointer): DWORD; stdcall;
var
  i: Integer;
beginfor i := 0 to 1000 do
  begin
    //使用WaitForSingleObject访问互斥对象,如果hMutex为被锁定>=1,那就等待,如果为未锁定那么就给hMutex的上锁,然后运行下面的代码
    if WaitForSingleObject(hMutex, INFINITE) = WAIT_OBJECT_0 then
    begin      //保护中的代码
      .....
      
      //代码结束后释放信号量,表示当前线程已经完成处理,后面的线程就可以获得控制权
      ReleaseMutex(hMutex);
    end;
  end;
  Result := 0;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
  hMutex := CreateMutex(nil, False, nil);//第二个参数为False表示创建的互斥对象不被任何线程拥有,也就说初始状态为未锁定,线程可以占有
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  CloseHandle(hMutex);
end;

end.
总的过程和临界区有些类似,只不过互斥对象是系统核心对象,可以跨进程,而临界区只是当前进程。有这个特性可以用于对文件等资源的并发保护。
4、信号量
 信号量与互斥对象的方法类似,信号量的特点是可以设置计数,就是同时可以允许多个线程同时访问同一段代码。互斥对象就是信号量为1的情况,后面的线程只能等前一个执行完,而信号量就可以允许指定多个执行。
 
 
后来在看TThread的代码时发现新的Delphi版本中有了一个好东西:TMnitor
try
      TMonitor.Enter(ThreadLock);
      try
        SyncProcPtr.Queued := QueueEvent;
        if SyncList = nil then
          SyncList := TList.Create;
        SyncProcPtr.SyncRec := ASyncRec;
        SyncList.Add(SyncProcPtr);
        SignalSyncEvent;
        if Assigned(WakeMainThread) then
          WakeMainThread(SyncProcPtr.SyncRec.FThread);
        if not QueueEvent then
          TMonitor.Wait(SyncProcPtr.Signal, ThreadLock, INFINITE)
      finally
        TMonitor.Exit(ThreadLock);
      end;
这个代码和java中的Synchronized代码块很像,这样写起线程同步要简化不少。

 

以上是关于delphi线程的主要内容,如果未能解决你的问题,请参考以下文章

delphi TerminateThread 结束一个线程后内存残留

delphi 没有handle时如何强行终止线程?

【delphi线程】 如何自动释放?

delphi 的多线程问题

delphi 在线程A中终止线程B

delphi多线程参数传递问题