2012年1月9日 星期一

[C++] Mutex


1. 同一個時間內只能夠有一個執行緒擁有mutex。
2. 同一個時間內只能夠有一個執行緒進入critical section。
3. Mutex速度較慢。因為Critical Section不需要進入OS核心,直接在User Mode 就可以進行動作。
4. Mutex可以跨Process使用。Critical Section則只能夠在同一個Process使用。
5. 等待一個mutex時,你可以指定『結束等待』時間長度,但對於critical section則不行。

用CreateMutex來產生Mutex
HANDLE WINAPI CreateMutex(
  __in_opt  LPSECURITY_ATTRIBUTES lpMutexAttributes,
  __in      BOOL bInitialOwner,
  __in_opt  LPCTSTR lpName
);
// The name can have a "Global\" or "Local\" prefix to explicitly create the object in the global or session namespace. The remainder of the name can contain any character except the backslash character (\).
用ReleaseMutex來釋放Mutex
BOOL WINAPI ReleaseMutex(
  __in  HANDLE hMutex
);
簡單的範例
CMutex::CMutex(std::wstring wstrMutexName)
{
 std::wstring wstrMutex = L"Global\\";
 wstrMutex += wstrMutexName;
 m_mutex = ::CreateMutex(NULL, FALSE, wstrMutex.c_str());
}

CMutex::~CMutex()
{
 ::CloseHandle(m_mutex);
}

HRESULT CMutex::Lock()
{
  HRESULT hr = E_FAIL;
 DWORD dRet = WaitForSingleObject(m_mutex, INFINITE);
 switch (dRet)
 {
  case WAIT_TIMEOUT:  // Time out
   break;
  case WAIT_OBJECT_0:  // Process over
    hr = S_OK;
   break;
  case WAIT_OBJECT_0 + 1: // Don't Know
   break;
 }
 return hr;
}

void CMutex::Unlock()
{
 ::ReleaseMutex(m_mutex);
}
如果想要利用Mutex讓一個Process在同一時間只被執行一次的話,可以用下列的方法檢查

1.Mutex的Create是否有Error
CMutex g_vthumbMutex(strModuleName);
if (GetLastError() == ERROR_ALREADY_EXISTS)
{
 return;
}
2. 用OpenMutex
HANDLE WINAPI OpenMutex(
  __in  DWORD dwDesiredAccess,
  __in  BOOL bInheritHandle,
  __in  LPCTSTR lpName
);
Reference:

沒有留言:

張貼留言