WaitReturn:=WaitForSingleObject(HMutex,0)
检查互斥对象HMutex的状态代码如下:
  WaitReturn:=WaitForSingleObject(HMutex,0)   //超时设置为0,只检查HMutex是否处于发信号状态
  if WaitReturn=Wait_Object_0 then         //处于发信号状态    
  begin
    ...
    ...
    ReleaseMutex(HMutex);             // //?????此处是否需要ReleaseMutex? 释放HMutex所有权
  end
  else if WaitReturn=Wait_TimeOut then     //超时
  begin
    ...
    ...
    ReleaseMutex(HMutex);             // //?????此处是否需要ReleaseMutex? 释放HMutex所有权
  end 
  else if WaitReturn=Wait_Abandoned then   //拥有该互斥对象的线程未释放此对象的所有权之前就已终止
  begin
    ...
    ...
    ReleaseMutex(HMutex);            //?????此处是否需要ReleaseMutex? 释放HMutex所有权
  end;

解决方案 »

  1.   

    ReleaseMutex只有在该线程拥有互斥对象时,才能生效。一个线程与一个互斥对象建立拥有关系,有两种方式:1、创建互斥对象时,传入 设置参数bInitialOwner ;2、使用wait函数,等待获取;WaitForSingleObject 只有在互斥对象有信号时,才使线程拥有这个互斥对象。所以Wait_TimeOut 不必释放
      

  2.   

    Avan_Lau兄:
       if WaitReturn=Wait_Abandoned then //拥有该互斥对象的线程未释放此对象的所有权之前就已终止
    如果某个线程未释放互斥对象的所有权就已终止,那其它线程是永远无法再获得该互斥对象的所有权了??
      

  3.   

    此处是否需要ReleaseMutex? 释放HMutex所有权
    ---------------------------
    Wait_Object_0 后都需要 ReleaseMutex, 来释放互斥所有权的  if WaitReturn=Wait_Abandoned then //拥有该互斥对象的线程未释放此对象的所有权之前就已终止
    如果某个线程未释放互斥对象的所有权就已终止,那其它线程是永远无法再获得该互斥对象的所有权了??
    ----------------------------
    Wait_Abandoned  是互斥对象已经失效了,应该是不需要 ReleaseMutex
      

  4.   

    那如果互斥对象失效那永远也无法再处于Wait_Object_0了,即所有线程都无法获得该互斥对象的所有权了?
      

  5.   

    但是waitfor的那个线程依然可以获取 互斥对象的拥有权,所以当你自己处理完之后,需要ReleaseMutex
      

  6.   

    应该是不需要的
    MSDN上没有说明 Wait_Abandoned 的是否必须释放的
    但是给的Example Code 上是没有释放的MSDN CodeBOOL FunctionToWriteToDatabase(HANDLE hMutex) 

        DWORD dwWaitResult;     // Request ownership of mutex.
     
        dwWaitResult = WaitForSingleObject( 
            hMutex,   // handle to mutex
            5000L);   // five-second time-out interval
     
        switch (dwWaitResult) 
        {
            // The thread got mutex ownership.
            case WAIT_OBJECT_0: 
                __try { 
                    // Write to the database.
                }             __finally { 
                    // Release ownership of the mutex object.
                    if (! ReleaseMutex(hMutex)) 
                    { 
                        // Deal with error.
                    }                 break; 
                }         // Cannot get mutex ownership due to time-out.
            case WAIT_TIMEOUT: 
                return FALSE;         // Got ownership of the abandoned mutex object.
            case WAIT_ABANDONED: 
                return FALSE; 
        }    return TRUE; 
    }所以我觉得在 WAIT_ABANDONED的情况下, 是不需要ReleaseMutex的
    一般ReleaseMutex也只有在Wait_Object_0  下处理
      

  7.   

    我觉得WAIT_ABANDONED  下的情况, 其实是没有互斥所有权的
      

  8.   

    MSDN
    WAIT_ABANDONEDThe specified object is a mutex object that was not released by the thread that owned the mutex object before the owning thread terminated. Ownership of the mutex object is granted to the calling thread and the mutex is set to nonsignaled.If the mutex was protecting persistent state information, you should check it for consistency.之前占有互斥对象的线程没有释放互斥对象,该线程就终止了。
      

  9.   

            // Got ownership of the abandoned mutex object.
            case WAIT_ABANDONED: 
                return FALSE; 
    demo注释也说明获取到拥有权了。返回false,表示不成功。但实际上还是有人当作是成功的来用。
    至于为什么没有release,可能还需要验证看看...
      

  10.   

    我的验证代码unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, SyncObjs, StdCtrls;type
      TForm1 = class(TForm)
        Button1: TButton;
        Button2: TButton;
        procedure FormDestroy(Sender: TObject);
        procedure Button1Click(Sender: TObject);
        procedure Button2Click(Sender: TObject);
        procedure FormCreate(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;
      f: Integer;      {用这个变量协调一下各线程输出的位置}
      gMutex: THandle;implementation{$R *.dfm}function ThreadFun1(p: Pointer): DWORD; stdcall;
    begin
      if WaitForSingleObject(gMutex, INFINITE) = WAIT_OBJECT_0 then
      begin
        Form1.Canvas.TextOut(0, 0, 'ThreadFun1.Exit');
        Exit;
      end;  Result := 0;
    end;function ThreadFun2(p: Pointer): DWORD; stdcall;
    begin
      case WaitForSingleObject(gMutex, INFINITE) of
         WAIT_OBJECT_0: ReleaseMutex(gMutex);
         Wait_Abandoned:
         begin
           // 只是证明  Wait_Abandoned有被执行到
           Form1.Canvas.Lock;
           Form1.Canvas.TextOut(0, 20, 'ThreadFun2.Wait_Abandoned');
           Form1.Canvas.Unlock;
         end;
      else ;
      end;  Result := 0;
    end;function ThreadFun3(p: Pointer): DWORD; stdcall;
    var
      I: Integer;
    begin
     for  I := 0 to 10000 do
      begin
        if WaitForSingleObject(gMutex, INFINITE) = WAIT_OBJECT_0 then
        begin
          Form1.Canvas.Lock;
          Form1.Canvas.TextOut(0, 40, IntToStr(i));
          Form1.Canvas.Unlock;
          ReleaseMutex(gMutex);
        end;
      end;
      Result := 0;
    end;
    procedure TForm1.FormDestroy(Sender: TObject);
    begin
      CloseHandle(gMutex);
    end;procedure TForm1.Button1Click(Sender: TObject);
    var
      ThreadID: DWORD;
    begin
      CloseHandle(CreateThread(nil, 0, @ThreadFun1, nil, 0, ThreadID));
      Sleep(100); //  保证第一个线程运行结束
      CloseHandle(CreateThread(nil, 0, @ThreadFun2, nil, 0, ThreadID));
    end;procedure TForm1.Button2Click(Sender: TObject);
    var
      ThreadID: DWORD;
    begin
      CloseHandle(CreateThread(nil, 0, @ThreadFun3, nil, 0, ThreadID));
    end;procedure TForm1.FormCreate(Sender: TObject);
    begin
      gMutex := CreateMutex(nil, False, nil);
    end;end.
      

  11.   

    第一个线程 没有释放互斥对象就强制退出线程
    第二个线程 主要为WaitForSingleObject出现 Wait_Abandoned的情况
    第三个线程 主要为测试是否能拿到互斥对象测试第二个线程 wait_Abandoned的情况 如果没有ReleaseMutex, 
    第三个线程 第一次WaitForSingleObject 会出现 wait_Abandoned的情况,拿到互斥对象
    下一次 WaitForSingleObject才会进入WAIT_OBJ ECT_0
    如果第二个线程 wait_Abandoned的情况下ReleaseMutex
    第三个线程 第一次WaitForSingleObject 就可以进入 WAIT_OBJ ECT_0所以wait_Abandoned 的情况下, 应该还是要ReleaseMutex 
      

  12.   

    经过两位的讨论解释 可以理解为在Wait_Abandoned的情况下,别的线程依然是可以取得该互斥对象所有权的,该互斥对象依然是有效的!
      

  13.   

    是不是可以理解为Wait_Abandoned的情况下,互斥对象既不处于发信号状态,也不处于不发信号状态,但是可以让WaitForSingleObject迅速返回,而且返回值为Wait_Abandoned
      

  14.   

    The specified object is a mutex object that was not released by the thread that owned the mutex object before the owning thread terminated. Ownership of the mutex object is granted to the calling thread and the mutex is set to nonsignaled. 设置无信号状态If the mutex was protecting persistent state information, you should check it for consistency.WaitForSingleObject迅速返回,而且返回值为Wait_Abandoned
    这种写法不对的。
    得分两种情况, 第一次Wait_Abandoned的情况下, 如果ReleaseMutex该互斥对象,另外的线程是可以进入
    WAIT_OBJ ECT_0,
    如果 第一次Wait_Abandoned的情况下没有ReleaseMutex该互斥对象, 则另外的线程进入还需要先进入一次
    Wait_Abandoned来拿到互斥所有权,然后该线程WaitForSingleObject下一次就可以进入WAIT_OBJ ECT_0
      

  15.   

    wait_Abandoned 的情况下要不要ReleaseMutex不知道, 但是ReleaseMutex是绝对安全的
      

  16.   

    感觉当Wait_Abandoned时互斥对象所有权不为任何对象所有,这时先取得Wait_Abandoned这个状态的线程可以释放已终止线程的互斥对象所有权.(而一般情况下互斥对象的所有权只能由占有所有权的线程释放)