写此技术共享贴的目的:
1.这两天工作要用到线程,故学习相关知识
2.前一段时间回答过几个有关于线程的问题
最主要目的是为大家更快地解决问题!现想总结一下线程常用的知识,如有不对之处,请高手(如僵哥等)补充并给个批注!1.如不用时间控件,实现用线程以做周期循环处理
2.访问界面控件时注意事项
VCL(TCanvas除外)都是假设为单线程进行处理的,所以在线程中处理与UI交互时,要委托主线程帮它们处理
3.正常地退出线程(非正常退出线程时,线程内的资源不能正常的释放,有时会出一些错误)
4.在单线程环境下,大家都用TList来存储对象,在多线程的环境下,可以直接用ThreadList来存储对象,因为它已经有了临界区功能
5.线程互斥(改天写例子)
:)下面是我写的一个极简单的线程代码,用来实现累加,且每隔一定的周期进行累加一次,累加之后将值传入控件中,在停止计算时通知线程结束!//线程类
unit Unit2;interfaceuses
  Classes,sysutils,SyncObjs,Dialogs;
type
  TTest = class(TThread)
  private
    { Private declarations }
    FSum:Integer;
    procedure UpdateCaption;
  protected
    procedure Execute; override;
  public
    constructor Create(CreateSuspended: Boolean);
  end;
implementation
uses Unit1;procedure TTest.UpdateCaption;
begin
  Form1.Edit1.Text := Inttostr(FSum);
  showmessage('Sum Process End');
end;procedure TTest.Execute;
begin
//必须循环来判断Terminated标志
  while not Terminated do
  begin
    FSum:=FSum+1;//这里可以执行其它独立的任务,例如生成带有独立任务的线程
    case QuitEvent.WaitFor(60*100) of  //阻塞时间,即Timer.Interval
      wrSignaled, wrAbandoned: Terminate;
    end;
      Synchronize(UpdateCaption);//实现问题2,把函数放在这里,是为了更直观地看到当前执行的结果
  end;
  { Place thread code here }
end;constructor TTest.Create(CreateSuspended: Boolean);
begin
  inherited;
  FSum:=0;
end;end.
//主线程代码
unit Unit1;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls,SyncObjs;type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
  procedure NotifySumThreadsToQuit;var
  Form1: TForm1;
  QuitEvent: TEvent;//事件说白了就是一个全局的布尔变量,用SetEvent置为一种状态,便于在线程循环时根据该标识来将线程中止
implementationuses Unit2;{$R *.dfm}procedure NotifySumThreadsToQuit;
begin
  QuitEvent.SetEvent;//置信号
end;procedure TForm1.Button1Click(Sender: TObject);
var
  Thd:TTest;
begin
  Thd:=TTest.Create(True);
  Thd.FreeOnTerminate:=False;
  Thd.Resume;
end;procedure TForm1.Button2Click(Sender: TObject);
begin
   NotifySumThreadsToQuit//通知线程结束
end;initialization
  QuitEvent := TEvent.Create(nil,true,false,'SumProcessEnd');//创建事件finalization
  QuitEvent.Free;//释放事件
end.

解决方案 »

  1.   


    procedure TTest.Execute;
    begin
    //必须循环来判断Terminated标志
      while not Terminated do
      begin
        FSum:=FSum+1;//这里可以执行其它独立的任务,
         //例如生成带有独立任务的线程,若不考虑用线程池,仅需要将新生成的线程的FreeOnTerminated:=True,就可以使它自生自灭了:)
        
        case QuitEvent.WaitFor(60*100) of  //阻塞时间,即Timer.Interval
          wrSignaled, wrAbandoned: Terminate;
        end;
          Synchronize(UpdateCaption);//实现问题2,把函数放在这里,是为了更直观地看到当前执行的结果
      end;
      { Place thread code here }
    end;
      

  2.   

    Faint~
    没人顶~
    睡觉!
      

  3.   

    线程是分2大类的,一种是工作者线程,一种是用户界面线程.怎么现在的程序员好象只会工作者线程的编程,用户界面线程好象提都没人提起.回调函数,消息泵这些古老的基础概念已经被现在的快速开发工具掩盖的不见踪迹了,真不知道该高兴还是悲哀.思维有点乱了,乱感慨下,别介意.ThreadList有临界区功能,感谢楼主.我一直没有注意到,还一直自己写代码控制同步,以后确实可以简化程序.
      

  4.   

    在VCL体系当中,UI线程,基本上可以认为只有主线程。
      

  5.   

    QuitEvent.WaitFor(60*100)

    WaitForSingleObject(QuitEvent, 60*100)
    的区别,是不是上面有的返回值,而下面的没有?我一般喜欢用下面的形式。
      

  6.   

    CSDN 怎么啦,  居然不回复  ,说内容太短
    无语
      

  7.   

    两者都有返回值,在一般情况下,前者也是调用后者完成的。但是前者会在实现了一个RPC当中的同步机制。
      

  8.   

    感觉没区别
    WaitFor就是用WaitForSingleObject实现的function TEvent.WaitFor(Timeout: LongWord): TWaitResult;
    begin
      case WaitForSingleObject(Handle, Timeout) of
        WAIT_ABANDONED: Result := wrAbandoned;
        WAIT_OBJECT_0: Result := wrSignaled;
        WAIT_TIMEOUT: Result := wrTimeout;
        WAIT_FAILED:
          begin
            Result := wrError;
            FLastError := GetLastError;
          end;
      else
        Result := wrError;    
      end;
      

  9.   


    可以具体讲讲吗?RPC同步
      

  10.   

    RPC同步,就是调用CoWaitfor***,用于影响RPC消息。
      

  11.   

    RPC同步,就是调用CoWaitfor***,用于响应RPC消息。
      

  12.   

    举例?贴几百行代码还是?http://msdn.microsoft.com/en-us/library/ms680732(VS.85).aspxhttp://books.google.com/books?id=HeQoWCQ_S9wC&pg=PA190&dq=CoWaitforMultipleHandles&sig=oqTtVSdG6A_Mh_TmLDaabxq6QLk
      

  13.   

    m        a          r          k
      

  14.   

    procedure TTest.Execute;
    begin
    //必须循环来判断Terminated标志
      while not Terminated do
      begin
        FSum:=FSum+1;//这里可以执行其它独立的任务,
         //例如生成带有独立任务的线程,若不考虑用线程池,仅需要将新生成的线程的FreeOnTerminated:=True,就可以使它自生自灭了:)
        
        case QuitEvent.WaitFor(60*100) of  //阻塞时间,即Timer.Interval
          wrSignaled, wrAbandoned: Terminate;
        end;
          Synchronize(UpdateCaption);//实现问题2,把函数放在这里,是为了更直观地看到当前执行的结果
      end;
      { Place thread code here }
    end;
      

  15.   

    QuitEvent: TEvent;需要和其他线程共享吗?为什么不把它放到线程类TTest的内部,在TTest的构造函数和析构函数里创建和释放?
    然后提供一个public方法让外部对其SetEvent。
    这样这个线程类复用起来也比较方便
      

  16.   

    你们说说看.网络游戏中那些怪物npc等的控制代码应该是多线程的吧.象魔兽世界这个游戏,虚拟世界的怪物和npc怕有几十个,每个怕都有一个线程在控制的吧.几十万个线程,想想都觉得不可思义.怎么编写出来的呢?