zoukankan      html  css  js  c++  java
  • Delphi多线程编程之四 线程安全和VCL

    1. ◆Delphi多线程编程之四 线程安全和VCL ◆(乌龙哈里2008-10-12)
    2. (调试环境:Delphi2007+WinXPsp3 例程:Tst_Thread4.dpr)
    3.     由于Delphi VCL在设计成大部分在主线程访问,因而,当多个线程同时访问VCL时,就非安全。
    4. 其实线程的安全性如上面那个读全局变量来说,那个全局变量是非线程安全的,因为当另外一个线程访问它的时候,它的数值还在被前一个线程改动中。这在非线程安全的对象中就会造成很严重的后果,比如一个对象的创立时的初始值被另一个线程改变了,后果相当地严重。
    5. VCL中,连很基础的Tlist都是非线程安全,要多个线程操纵List时,用TThreadList来替代。
    6. unit Tst_Thread4U;
    7. interface
    8. uses
    9.   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
    10.   Dialogs, StdCtrls;
    11. type
    12.   TForm1 = class(TForm)
    13.     Button1: TButton;
    14.     Memo1: TMemo;
    15. procedure Button1Click(Sender: TObject);
    16. procedure Button2Click(Sender: TObject);
    17. private
    18. { Private declarations }
    19. public
    20. { Public declarations }
    21. end;
    22.   TMyThread=class(TThread)
    23. protected
    24. procedure Execute;override;
    25. procedure ShowInMemo;
    26. end;
    27. var
    28.   Form1: TForm1;
    29. implementation
    30. {$R *.dfm}
    31. const
    32.   MaxSize=1000;
    33. var
    34.   NextNumber:Integer=0;
    35.   GlobalNum:Integer;
    36. function GetNextNumber:Integer;
    37. begin
    38.   Result:=NextNumber;
    39.   inc(NextNumber);
    40. end;
    41. { TMyThread }
    42. procedure TMyThread.Execute;
    43. var
    44.   i:Integer;
    45. begin
    46.   FreeOnTerminate:=True; //终止后自动free
    47. for i := 1 to MaxSize do
    48. begin
    49.     GlobalNum:=GetNextNumber;
    50.     Sleep(5);
    51.     Synchronize(ShowInMemo);
    52. //  ShowInMemo;
    53. end;
    54. end;
    55. procedure TMyThread.ShowInMemo;
    56. begin
    57.     Form1.Memo1.Lines.Add(inttostr(GlobalNum));
    58. end;
    59. procedure TForm1.Button1Click(Sender: TObject);
    60. begin
    61.   TMyThread.Create(False);
    62.   TMyThread.Create(False);
    63. end;
    64. end.
    65. 上面这个例程,把输出到Memo1放在线程里了,所以要在Execute()内用到Synchronize()函数,这样才是线程安全。
    66. 一、Synchronize()函数。
    67.     是个重载函数,有两种引用形式:
    68. class procedure Synchronize(AThread: TThread; AMethod: TThreadMethod); overload;
    69. procedure Synchronize(AMethod: TThreadMethod); overload;
    70. Amethod是线程的一个自定义不带参数过程(!!太烦了,不能带参数,好不方便)。
    71. Synchronize()调用了Windows的SendMessage()向主线程发一消息。主线程必须已建立消息队列,并且不断地从消息队类中检索消息。一旦主线程检索到消息,就执行Synchronize()所指定的代码。(ps:我查了Vcl源程序,发现也是调用临界区,这个太不方便了,还是使用临界区好)。
  • 相关阅读:
    win8应用的编码UI测试
    什么是Peer Review
    Android开发环境的搭建
    运用int.parse()判断闰年代码实现
    等价类划分方法的应用之EditBox(二)
    等价类划分方法的应用之EditBox
    集成测试
    数据可视化简介
    关于processing
    白盒测试VS黑盒测试
  • 原文地址:https://www.cnblogs.com/94YY/p/2199345.html
Copyright © 2011-2022 走看看