delphi多线程

作者: bshoes | 来源:发表于2019-07-24 22:25 被阅读0次

    Delphi通过线程类TThread 极大地简化了windows的多线程API函数操作。但是TThread 对象是没有实例的。它和界面交流主要靠主线程。那么核心问题就是线程的同步了。

一、线程与主线程同步方式常用的2种:

1、使用Synchronize方法(这个方法用于访问VCL 主线程所管理的资源)

procedure Theater.Execute;

      begin

        Synchronize(DoS);   

      end; 

 procedure Theater.DoS;

      begin

        ......... 

      end; 

2、使用消息(这个方法也可用于进程之间的通信)

主窗口定义一个消息

const   MSG_DTSCROLL  = WM_USER + 2020;

procedure MsgDtScroll(var Msg: TMessage); message MSG_DTSCROLL;//声明

procedure TMainF.MsgDtScroll(var Msg: TMessage);

begin

........

end;

线程发送消息

procedure Theater.Execute;

      begin

      PostMessage(Handle, MSG_DTSCROLL, 0, 0);  

      end; 

另外还有些控件对象内部提供了线程的同步机制,如TCanvas可以使用其提供的Lock方法用于线程的同步

上面解决了线程和主线程同步问题,可是如果有2个线程同时访问一个控件应该如何处理。使用临界区就可以解决这个问题

二、线程同步之临界区

uses SyncObjs;

var

  CS: TCriticalSection; //界面创建时要初始化  界面销毁时要释放

function MyThreadFun(p: Pointer): DWORD; stdcall;

var

  i: Integer;

begin

  CS.Enter;

for i := 0 to 99 do Form1.ListBox.Items.Add(IntToStr(i));

  CS.Leave;

  Result := 0;

end;

另外已经启动的线程,我们如何检测执行状态,来判断是否做其他操作。

三、检测线程执行状态

//返回值:0-已释放;1-正在运行;2-已终止但未释放;3-未建立或不存在

function CheckThreadFreed(aThread: TThread): Byte;

var

  I: DWord;

  IsQuit: Boolean;

begin

  if Assigned(aThread) then

  begin

    IsQuit := GetExitCodeThread(aThread.Handle, I);

    if IsQuit then

    begin

    if I = STILL_ACTIVE then Result := 1

    else  Result := 2;

    end else Result := 0;

  end else Result := 3;

end;

四、其他注意事项

1.如果用到了ado控件需要使用CoInitialize(nil);初始化线程环境,线程结束前调用CoUninitialize();

2.线程类默认创建即启动,不启动创建时xxx.create(true);

3.线程类属性FreeOnTerminate设为true执行完就释放;

相关文章

网友评论

    本文标题:delphi多线程

    本文链接:https://www.haomeiwen.com/subject/xmjxfctx.html