TThread的Synchronize(Method: TThreadMethod)方法可以将method交由主线程执行,避免多线程冲突,但这样等于没有使用多线程性能。
能不能提供线程三种同步方式的示例,多谢啦。

解决方案 »

  1.   

    使用API函数建立多线程,然后自己同步线程,很稳定
      

  2.   

    轮训是最差的选择,因为浪费CPU资源而且自己做的标志可能会遇到问题比如两个线程都比较发现标志为空,然后这时候一个线程改变了标志为占用,另一个线程应该不能运行但是因为在前一个线程改变标志之前他一判断结束所以他会认为也执行,这样就会出现错误导致四季。
    最简单的方法就是用操作系统提供的同步机制正如洪峰鸟所说,这几个东西很简单帮助里有很好的例子,你可以在帮助里查找我这里没有装Delphi也没有Msdn所以没法给你查。
    你就查semaphore就可以了
      

  3.   

    CreateThread(),ExitThread(),ResumeThread()等API函数怎么用,能不能提供delphi的示例让我瞧瞧。
      

  4.   

    我给你贴个例子,是Delphi5开发人员指南里的
    用的是互斥
    unit Main;interfaceuses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
      StdCtrls;type
      TMainForm = class(TForm)
        Button1: TButton;
        ListBox1: TListBox;
        procedure Button1Click(Sender: TObject);
      private
        procedure ThreadsDone(Sender: TObject);
      end;  TFooThread = class(TThread)
      protected
        procedure Execute; override;
      end;var
      MainForm: TMainForm;implementation{$R *.DFM}const
      MaxSize = 128;var
      NextNumber: Integer = 0;
      DoneFlags: Integer = 0;
      GlobalArray: array[1..MaxSize] of Integer;
      hMutex: THandle = 0;function GetNextNumber: Integer;
    begin
      Result := NextNumber;  // return global var
      Inc(NextNumber);       // inc global var
    end;procedure TFooThread.Execute;
    var
      i: Integer;
    begin
      FreeOnTerminate := True;
      OnTerminate := MainForm.ThreadsDone;
      if WaitForSingleObject(hMutex, INFINITE) = WAIT_OBJECT_0 then
      begin
        for i := 1 to MaxSize do
        begin
          GlobalArray[i] := GetNextNumber;  // set array element
          Sleep(5);                         // let thread intertwine
        end;
      end;
      ReleaseMutex(hMutex);
    end;procedure TMainForm.ThreadsDone(Sender: TObject);
    var
      i: Integer;
    begin
      Inc(DoneFlags);
      if DoneFlags = 2 then    // make sure both threads finished
      begin
        for i := 1 to MaxSize do
          { fill listbox with array contents }
          Listbox1.Items.Add(IntToStr(GlobalArray[i]));
        CloseHandle(hMutex);
      end;
    end;procedure TMainForm.Button1Click(Sender: TObject);
    begin
      hMutex := CreateMutex(nil, False, nil);
      TFooThread.Create(False);  // create threads
      TFooThread.Create(False);
    end;
    end.
      

  5.   

    以下是我定义的TThread派生类:
    TDoorThread=class(TThread)
    private
     Current:smallint;
     InterTimes:Integer;        //线程轮询间隔
     ThreadMode:byte;    //线程模式,1-人工,2-自动,3-计划
     ThreadActed:boolean; //标示线程是否工作
     Successed:boolean;    //标示当前门控器数据采集是否成功
     procedure GatherDoorData;       //采集刷卡记录
     procedure CheckAuthor;          //检测UserAuthor表中是否有记录,有则导入Periods表并下载
     procedure DownLoadPeriods(address:smallint);
     procedure DecodeSetting(OldSetting:string);
    public
     procedure execute;override;
    end;TCommandThread=class(TThread)
    private
     Current:smallint;
     InterTimes:Integer;        //线程轮询间隔
     ThreadActed:boolean; //标示线程是否工作
     procedure DoCommand;       //执行WEB命令,操作门控器
    public
     procedure execute;override;
    end;以下是执行过程定义
    procedure TCommandThread.execute ;
    beginif planed then begin
     Current:=0;
     while current<Times do begin
      DoCommand;
      Inc(Current);
     end;
    end
    elsewhile true do begin
    try
     Sleep(1000*InterTimes);
     DoCommand;
     if not ThreadActed then  exit;
    except
     continue;
    end;
    end; //while
    end;procedure TDoorthread.execute ;
    begin
    case ThreadMode of
    1:
    begin
     GatherDoorData;
     CheckAuthor;
    end;
    2:
    while true do begin
     Sleep(1000*InterTimes);
     GatherDoorData;
     CheckAuthor;
     if not ThreadActed then  exit;
    end; //while
    3:
    begin
    Current:=0;
    while current<Times do begin
     GatherDoorData;
     CheckAuthor;
     Inc(Current);
    end; //while
    end;end;//caseend;我在这两个线程的execute过程中使用死循环不断执行一些过程,这些过程访问了相同的全局变量,全局变量多为pchar,在这两个线程创建之前已经分配内存。程序不够稳定,有死机现象。如何解决。
     rwdx(任我独行) ,请问你有没有API线程函数的demo,我在MSDN中只有函数说明,没有demo.
    哦,对了,semaphore是什么工具,我这里没有。
      

  6.   

    应该不管Thread什么问题,可能是由于你的线程中访问全局对象/变量所致。
    线程访问全局对象/变量,或者是引用关系的对象时,需要同步的支持,不然的话会经常出现“地址访问错:oxfffffdfdsf",什么什么的一般我们线程访问全局对象/变量/引用的对象,最简单的用Synchrize(ProcMethod),
    其它的还有:
    SyncObjs.TSimpleEvent, TEvent类
    CreateEvent  //建立一个事件,安全,是否自动设置为无信号(waitFor完成后),初始信号,名称
    WaitFor      //如果设置为自动无信号,waitFor会将Event设为无信号
    SetEvent     //设置有信号
    ResetEvent   //设置无信号CreateSemaphore  //建立信号,安全(nil),初始,最大引用计数器,名称
    WaitFor          //waitfor使Semaphore--,即说Semaphore的资源--,如超过最大计数器则阻塞进程
    ReleaseSemaphore  //将Semaphore++CreateMutex  //互斥信号,
    WaitFor     //将信号lock,不成功则阻塞进程
    ReleaseMutex  //工作做完了,将信号UnLock,别的线程才能waitforWaitFor ==> WaitForSingleObject, WaitForMutpleObjects, Msg....还有TCriticalSection就比较简单了,不说了
    具体方面具体使用了,看它适合哪方面。
    最后记住CloseHandle(Event/Semaphore/Mutex);你说的Semaphore就是CreateSemaphore之类的。
      

  7.   

    是资源冲突还是CPU过忙造成的吗?
    application.ProcessMessages();
      

  8.   

    全局变量的访问一定要用TCriticalSection(为什么不用TSimpleEvent, TEvent?搞那么负责干什么,在一个application中的thread,用TCriticalSection就足够啦)
    访问数据前:TCriticalSection.enter,访问完毕后用TCriticalSection.leave祝你好运
      

  9.   

    suvi() ,TCriticalSection在delphi帮助中没有demo,怎么用,是否这样
    type
    TDoorThread=class(TThread)
    private
     Current:smallint;
     InterTimes:Integer;        //线程轮询间隔
     ThreadMode:byte;    //线程模式,1-人工,2-自动,3-计划
     ThreadActed:boolean; //标示线程是否工作
     Successed:boolean;    //标示当前门控器数据采集是否成功
     procedure GatherDoorData;       //采集刷卡记录
     procedure CheckAuthor;          //检测UserAuthor表中是否有记录,有则导入Periods表并下载
     procedure DownLoadPeriods(address:smallint);
     procedure DecodeSetting(OldSetting:string);
    public
     procedure execute;override;
    end;
    var 
    iCriticalSection:TCriticalSetion;procedure Tform1.create(Sender: TObject);
    begin
     iCriticalSection:=TCriticalSetion.create;
    end;procedure TDoorthread.execute ;
    begin
    iCriticalSection.enter;  //加上这句case ThreadMode of
    1:
    begin
     GatherDoorData;
     CheckAuthor;
    end;
    2:
    while true do begin
     Sleep(1000*InterTimes);
     GatherDoorData;
     CheckAuthor;
     if not ThreadActed then  exit;
    end; //while
    3:
    begin
    Current:=0;
    while current<Times do begin
     GatherDoorData;
     CheckAuthor;
     Inc(Current);
    end; //while
    end;end;//case
    iCriticalSection.leave;//加上这句end;其他的线程execute方法中也写上上述两句iCriticalSection.enter和TCriticalSection.leave?这样写能解决问题吗?