互斥和信號量是多線程編程的兩個基礎,其原理就不詳細說了,大家去看看操作系統的書或者網上查查吧。
對於互斥的實現,無論什麼操作系統都離不開三個步驟
1.初始化互斥鎖
2.鎖操作
3.解鎖操作
對於不同的系統只是實現的函數有一些不同而已,但是功能其實都大同小異,在鎖操作和解鎖操作的時候大部分系統都有超時機制在裡面,來保證不會一直鎖在某個地方,我們為了框架簡單,沒有設置超時,進行鎖操作的時候如果得不到鎖,將一直等待在那裡。
Mutex的基類我們描述如下
[cpp] class CMutex
{
public:
CMutex(const char *pName = NULL); //初始化鎖
~CMutex();
virtual bool Lock()=0; //鎖操作,純虛函數
virtual bool UnLock()=0; //解鎖操作,純虛函數
const char * getName(void) const {
return mutex_name;
}
protected:
char *mutex_name; //鎖名字
};
class CMutex
{
public:
CMutex(const char *pName = NULL); //初始化鎖
~CMutex();
virtual bool Lock()=0; //鎖操作,純虛函數
virtual bool UnLock()=0; //解鎖操作,純虛函數
const char * getName(void) const {
return mutex_name;
}
protected:
char *mutex_name; //鎖名字
};
對於每個系統的實現,都需要完成初始化,鎖操作,解鎖操作三個部分,在linux下,這三個操作都很簡單,就不在這裡貼代碼了。
同樣,對於信號量Sem,每個系統的實現也大同小異,無非就是
1.初始化信號量
2.發送信號量(信號量+1)
3.接收信號量(信號量-1)
Sem基類描述如下
[cpp] class CCountingSem
{
public:
typedef enum {
kTimeout,
kForever
}Mode;
CCountingSem(); //初始化信號量
~CCountingSem();
virtual bool Get() = 0; //接收信號量
virtual bool Post(void) = 0; //發送信號量
};
class CCountingSem
{
public:
typedef enum {
kTimeout,
kForever
}Mode;
CCountingSem(); //初始化信號量
~CCountingSem();
virtual bool Get() = 0; //接收信號量
virtual bool Post(void) = 0; //發送信號量
};
同樣,具體實現就不貼代碼了。
當然,對於一個滿足設計模式的系統,新建互斥鎖和信號量的時候當然不能直接new這些類啦,必然還要通過簡單工程來返回,在COperatingSystemFactory類中添加newMutex和newCountingSem方法,通過COperatingSystemFactory對操作系統的判斷來返回相應的實體。
[cpp] class COperatingSystemFactory
{
public:
static COperatingSystem *newOperatingSystem();
static CCountingSem *newCountingSem(unsigned int init=0); //參數是信號量的初始值,一般為0
static CMutex *newMutex(const char *pName=NULL);
};
class COperatingSystemFactory
{
public:
static COperatingSystem *newOperatingSystem();
static CCountingSem *newCountingSem(unsigned int init=0); //參數是信號量的初始值,一般為0
static CMutex *newMutex(const char *pName=NULL);
};
好了,有了互斥和信號量,怎麼用呢,在main函數中,我們可以先申請好互斥鎖和信號量,如果我們啟了很多線程,如果某幾個之間需要互斥鎖,那我們將申請好的互斥鎖賦值給相應的線程,就可以直接使用了。至於各個線程類,是你自己寫的,只是繼承自CThread而已,裡面的成員變量怎麼和main中申請的互斥鎖關聯,這就不用說了吧,你把它設置成public賦值也行,設置從private用函數set也行,一切看你啦。
有了互斥鎖和信號量,下面就可以起消息隊列了,有了消息隊列,一個最簡單的多線程模型也就完成了。