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