如果有多个线程同时在
WaitForSingleObject
一个Event
当之前运行的一个线程SetEvent后
那么同时等待的其他线程将会同时收到这个信号而执行下面的代码,这样又会造成冲突
请问如何避免,或者如何使系统按照类似队列的方式先进先出的运行?

解决方案 »

  1.   

    CreateEvent时,第2参数给FALSE。
      

  2.   


    第二个参数
     bManualReset               创建的Event是自动复位还是人工复位     ,如果true,人工复位,   
        一旦该Event被设置为有信号,则它一直会等到ResetEvent()API被调用时才会恢复   
        为无信号.     如果为false,Event被设置为有信号,则当有一个wait到它的Thread时,   
        该Event就会自动复位,变成无信号.   这个好像和我的疑惑没什么关系
      

  3.   

    如果这个参数给FALSE,不管有多少线程等待该事件,只会有一个线程得到信号。
      

  4.   

    排队的话,一般用临界就行了,不用临界的话,也可以用Semaphore
      

  5.   

    刚才写了一段测试代码,试了一下应该是触发一次,问题可能处在
    procedure WaitForTranEvent(FAdoconn:TAdoconnection);
    begin
     if FAdoConn.InTransaction then WaitForSingleObject(TranEventHandle,500);
    end;这个InTransaction不是用临界限制的,暂时不管了
      

  6.   

    测试代码:unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;procedure ThreadExecutePoc(P:Pointer);type
      TForm1 = class(TForm)
        Edit1: TEdit;
        Edit2: TEdit;
        Button1: TButton;
        Button2: TButton;
        Button3: TButton;
        procedure Button1Click(Sender: TObject);
        procedure Button2Click(Sender: TObject);
        procedure Button3Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.dfm}
    var
     EventHandle:THandle;procedure ThreadExecutePoc(P:Pointer);
    begin
     WaitForSingleObject(EventHandle,10000);
     if boolean(p) then
        Form1.Edit1.Text:='Event1'
     else
        Form1.Edit2.Text:='Event2';
     EndThread(0);
    end;procedure TForm1.Button1Click(Sender: TObject);
    var
    h:Thandle;
    t:cardinal;
    begin
     h:=beginthread(nil,0,@ThreadExecutePoc,Pointer(true),0,t);
    end;procedure TForm1.Button2Click(Sender: TObject);
    var
    h:Thandle;
    t:cardinal;
    begin
     h:=beginthread(nil,0,@ThreadExecutePoc,Pointer(false),0,t);
    end;procedure TForm1.Button3Click(Sender: TObject);
    begin
     setevent(EventHandle);
    end;initialization
     EventHandle:=CreateEvent(nil, FALSE, FALSE, nil)
    finalization
     CloseHandle(EventHandle);end.