zoukankan      html  css  js  c++  java
  • delphi多线程编程之二

    一、线程的局部变量threadvar

    1. type
    2.   TForm1 = class(TForm)
    3.     Button1: TButton;
    4.     Memo1: TMemo;
    5. procedure Button1Click(Sender: TObject);
    6. private
    7. { Private declarations }
    8. public
    9. { Public declarations }
    10. end;
    11.   TMyThread=class(TThread)
    12. private
    13.     FNewStr:string;
    14. protected
    15. procedure Execute;override;
    16. public
    17. constructor Create(const ANewStr:string);
    18. end;
    19. var
    20.   Form1: TForm1;
    21. implementation
    22. {$R *.dfm}
    23. var
    24.   n:integer;
    25. threadvar
    26.   GlobalStr:string;
    27. procedure SetShowStr(const S:string;Memo:TMemo);
    28. begin
    29. if s='' then
    30. //MessageBox(0,pchar(GlobalStr),'The String is...',MB_OK)
    31. begin
    32.     inc(n);
    33.     Memo.Lines.Add(inttostr(n)+GlobalStr);
    34. end else  GlobalStr:=S;
    35. end;
    36. constructor TMyThread.Create(const ANewStr: string);
    37. begin
    38.   FNewStr:=ANewStr;
    39.   Inherited Create(False);
    40. end;
    41. procedure TMyThread.Execute;
    42. begin
    43.   FreeOnTerminate:=True; //终止后自动free
    44.   SetShowStr(FnewStr, Form1.Memo1);
    45.   SetShowStr('', Form1.Memo1);
    46. end;
    47. procedure TForm1.Button1Click(Sender: TObject);
    48. begin
    49.   n:=1;
    50.   SetShowStr('Hello World', Form1.Memo1);   //Global:='Hello World'
    51.   SetShowStr('', Form1.Memo1);    //show 1Global
    52.   TMyThread.Create('Mygodsos');  //Global:='Mygodsos',show 2Global
    53.   Sleep(100);
    54.   SetShowStr('', Form1.Memo1);  //show 3Global 
    55. end;
    56. end.

    当GlobalStr 声明不同时,结果分别是:

    Threadvar var

    1Hello World 1Hello World

    3Hello World 3Mygodsos

    2Mygodsos 2Mygodsos

    Delphi利用关键字threadvar封装API线程局部存储。它能使你在第一个运行的线程中创建一个全局变量的拷贝。如果用ThreadVar声明变量,则在程序结束前必须手动释放其占用的空间(这个手动释放的问题不知道d2007解决没有?)

    (ps 我看到很多关于threadvar释放要 := ''的,若不是string类型的给如何释放?)

    二、双线程看看Threadvar:

    把Execute()里Create(False)改成Create(True)

    1. procedure TForm1.Button2Click(Sender: TObject);
    2. var
    3.   MyThread1:TMyThread;
    4.   MyThread2:TMyThread;
    5. begin
    6.   n:=0;
    7.   SetShowStr('Hello World',Form1.Memo1);   //Global:='Hello World'
    8.   SetShowStr('',Form1.Memo1);    //show Global
    9.   MyThread1:=TMyThread.Create('thread 1:');  //Global:='Mygodsos',show Global
    10.   MyThread2:=TMyThread.Create('thread 2:');  //Global:='Mygodsos',show Global
    11.   MyThread1.Resume;
    12.   MyThread2.Resume;
    13.   Sleep(100);
    14.   SetShowStr('',Form1.Memo1);  //show Global
    15. end;

    当GlobalStr 声明为不同,结果对比是:

    Threadvar Var

    1Hello World 1Hello World

    4Hello World 4thread 2:

    2thread 1: 3thread 2:

    3thread 2: 2thread 1:

    这里出现一个十分有趣的问题,若sleep()位置不同,结果不一样。

    MyThread1.Resume;

    Sleep(100);

    MyThread2.Resume;

    //Sleep(100);

    改成这样后,结果是:

    Threadvar Var

    1Hello World 1Hello World

    3Hello World 3thread 1:

    2thread 1: 2thread 1:

    4thread 2: 4thread 2:

    留意一下前面的序号,似乎sleep()的作用比较奇怪。

    三、Sleep()函数

    Win32API过程Sleep()。此过程声明如下:

    procedure Sleep(dwMilliseconds:DWORD); stdcall;

    Sleep()过程用来告诉操作系统,当前的线程在参数dwMilliseconds指定的时间内不需要分配任何CPU时间。插入这个调用是使很多的任务在发生时,使执行哪个线程有一些随机性。通常,可以把参数dwMilliseconds设为0。尽管,这并没有使当前的线程真的“睡眠”,但它使操作系统把CPU时间分给了其他优先级相等或更高的线程。要小心Sleep()神秘的时间调整问题。Sleep()可能会使你的机器出现特别的问题。这种问题在另一台机器上可能无法再现。

    对上面的例子,改回以下,把global设成var声明:

    MyThread1.Resume;

    MyThread2.Resume;

    Sleep(100);

    执行几次,结果:

    1Hello World 1Hello World

    4thread 2: 4thread 2:

    3thread 2: 2thread 1:

    2thread 1: 3thread 2:

    看来sleep后,在主进程中先返回哪个线程是有一定的随机性的。但前面的序号还是一样的,意思是虽然主进程返回哪个线程的次序不一样,但线程执行的次序还是没变。不知道我这样理解对不对。

  • 相关阅读:
    如何安装ArchLinux
    状态模式
    iOS设备的越狱方法
    浅析Windows安全相关的一些概念
    项目做成jar包
    JavaScript包装对象
    node.js系列笔记之node.js初识《一》
    使用Reactive Extensions(Rx),对短时间内多次发生的事件限流
    in和exists哪个效率高本人测试证明
    Asp.net MVC使用Filter解除Session, Cookie等依赖
  • 原文地址:https://www.cnblogs.com/94YY/p/2199343.html
Copyright © 2011-2022 走看看