CMutex

互斥(Mutex)是一種用途非常廣泛的核心對象。能夠保證多個執行緒對同一共享資源的互斥訪問。同臨界區有些類似,只有擁有互斥對象的執行緒才具有訪問資源的許可權,由於互斥對象只有一個,因此就決定了任何情況下此共享資源都不會同時被多個執行緒所訪問。當前占據資源的執行緒在任務處理完後應將擁有的互斥對象交出,以便其他執行緒在獲得後得以訪問資源。與其他幾種核心對象不同,互斥對象在作業系統中擁有特殊代碼,並由作業系統來管理,作業系統甚至還允許其進行一些其他核心對象所不能進行的非常規操作。只有擁有互斥對象並得以進入到共享資源,而其他執行緒則會被排斥在外。當此執行緒處理完共享資源並準備離開此區域時將把其所擁有的互斥對象交出,其他任何一個試圖訪問此資源的執行緒都有機會得到此互斥對象。

互斥對象在MFC中通過CMutex類進行表述。使用CMutex類的方法非常簡單,在構造CMutex類對象的同時可以指明待查詢的互斥對象的名字,在構造函式返回後即可訪問此互斥變數。CMutex類也是只含有構造函式這唯一的成員函式,當完成對互斥對象保護資源的訪問後,可通過調用從父類CSyncObject繼承的UnLock()函式完成對互斥對象的釋放。

基本介紹

  • 外文名:CMutex
  • 對象代表:啞程
  • 特點:允許某執行緒共同訪問同一資源
  • 要求:首先構造一個所需的CMutex 對象
介紹,CMutex類,實現,使用和用法,小結,

介紹

CMutex類的對象代表“啞程(mutex)”——它為一個同步對象,允許某執行緒共同訪問同一資源。在僅僅一個執行緒被允許用於修改數據或其它被控制的資源時,啞程將變得非常有用。例如,給連結的列表增添一個結點就是只允許一個執行緒的過程。通過使用CMutex對象來控制連結列表,此時只有一個執行緒能夠獲得列表的訪問權。
若要使用CMutex 對象,首先要構造一個所需的CMutex 對象。然後指定希望等待的啞程的名稱,那么套用最初就將擁有它。可以在構造函式返回時,訪問啞程。當你已經訪問了被控制的資源後,再調用CSyncObject::Unlock函式。
另外一種使用CMutex 對象的方法就是一個CMutex類型的變數,將其作為你希望控制類數據成員。在被控制對象的構造過程中,若啞程最初擁有了啞程的名稱或期待的安全屬性,那么就調用CMutex數據成員指定的構造函式,以這種方式訪問由CMutex 對象控制的資源,首先要在資源訪問的成員函式中創建CSingleLock類型或CMultiLock類型的變數。然後調用封鎖對象的Lock成員函式(例如, CSingleLock::Lock)。這樣,你的執行緒要么就獲得資源的訪問權,以等待將要釋放的資源,並獲取訪問權,要么就等待將要釋放的資源,當逾時後,返回失敗。在任何一種情況下,都可以在執行緒安全的模式下訪問資源。若要釋放這些資源,使用封鎖對象的Unlock成員函式(例如, CSingleLock::Unlock),或允許封鎖對象越界。

CMutex類

1、CMutex只是對 win32API 的互斥操作進行了封裝
2、它的參數與 win32 API 中的 CreatMutex() 相對應
3、CMutex的構造函式調用 CreatMutex() 創建並檢查
4、其Lock操作從基類繼承,調用WaitForSingleObject()獲得所有權,互斥類重載 Unlock 調用ReleaseMutex()釋放所有權。
所以,MFC其實就是簡單了封裝了 win32 API 函式。

實現

1、CMutex::CMutex(BOOL bInitiallyOwn, LPCTSTR pstrMame)
2、CMutex::~CMutex()
3、BOOL CMutex::Unlock()

使用和用法

首先,創建工程——win32 console Application——工程名——OK——an application that supports MFC——finish
1、例子1,單獨操作(偽代碼)
CMutex mutex; //聲明互斥
UINT mythreadA:mutex.Lock();
//動作
mutex.Unlock();
Sleep(1000);
UINT mythreadB:mutex.Lock();
//動作
mutex.Unlock();
Sleep(1000);
int _tmain():int flag=0;
if(!AfxWinInit(::GetModuleHandle(NULL),NULL,::GetCommandLine(),0))
{cerr<<.......... ; flag=1; }
else
{
AfxBeginThread(mythreadA,NULL);
AfxBeginThread(mythreadB,NULL);
Sleep(10000);
}
return flag;
2、這個例子(和CSingleLock使用):
1)通過某個成員函式訪問被 CMutex 對象保護的資源(即array[1024];)時,要創建CSingleLock或者是CMultiLock,它以 CMutex 對象的指針為參數。
2)然後調用 CSingleLock或CMultiLock的成員函式Lock()和Unlock()來獲取和釋放資源
3)這樣,在一個進程使用該類時,就不必擔心同步問題了。
#include"afxmt.h"//同步操作時需要包含的頭檔案
#include<iostream.h>
class CResourse //定義資源類
{
private:
int array[1024];
CMutex mutex; //此時互斥量受到保護
public:
CResourse();//構造函式
~CResourse();//析構函式
void setdata(int n ,int data);
int getdata(int n);
}
//以下為資源類內的公共函式初始化
CResourse::CResourse:mutex(FALSE,NULL)
{ for(int i=0;i<1024;i++) array[i]=0; }
CResourse::~CResourse() {}
void CResourse::setdata(int n, int data)
{
CSingleLock sLock(&mutex);
sLock.Lock();
if(sLock.IsLocked())
array[n]=data;
sLock.Unlock();
}
int CResourse::getdata(int n)
{
int t;
CSingleLock sLock(&mutex);
sLock.Lock();
if(sLock.IsLocked())
t=array[n];
sLock.Unlock();
return t;
}
UINT mythread1(LPVOID pParam);
UINT mythread2(LPVOID pParam);
CResourse res; //聲明全局變數
UINT mythread1(LPVOID pParam);
{ res.setdata(1,100); retuen 1; }
UINT mythread2(LPVOID pParam);
{ cout<<res.getdata(1)<<endl; retuen 1; }
int main(int argc, TCHAR* argv[], TCHAR* envp[] )
{
AfxBeginThread(mythread1,NULL);
AfxBeginThread(mythread2,NULL);
Sleep(1000);
return 1;
}

小結

上面兩個例子的區別主要是:
1、一個是CMutex的單獨使用,一個是CMutex和CSingleLock一起使用。
2、第一個是關於同步的問題;
3、第二個是關於資源類受到保護的問題。受到保護時,需要用CSingleLock或CMultiLock 間接訪問。

相關詞條

熱門詞條

聯絡我們