多年以后重发:多线程安全的变量模板
生活随笔
收集整理的這篇文章主要介紹了
多年以后重发:多线程安全的变量模板
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
大家好,這里是我以xghome這個用戶名,02年在CSDN上發(fā)布的《多線程安全的變量模板》,這次在《0bug -- C/C++商用工程之道》一書中,作為“資源鎖”和多線程通信核心示例,也再次出現(xiàn)。 這個模板我當(dāng)初大約寫了19遍,寫的有點長了,為了給廣大讀者省點事,我就把它粘貼過來了。嗯,原帖在這里:http://blog.csdn.net/xghome/archive/2002/05/28/15469.aspx xghome是我2005年以前在CSDN使用的用戶名,不過,可惜密碼搞忘了,最要命的是,注冊的21cn的郵箱也被廢除,搞得我只有以tonyxiaohome這個用戶名重出江湖。不過還是應(yīng)該夸一句,CSDN對用戶名和密碼的保護,真的沒話講,呵呵,我怎么也沒有辦法恢復(fù)原用戶名了。 嗯,這段代碼是我的代碼,我叫肖舸,拼音縮寫XG,那個時侯還沒用Tony.Xiao的英文名呢。大家注意了哈,可不是我欺世盜名,盜貼別人的帖子哈。 嗯,還有個旁證,我的《0bug -- C/C++商用工程之道》一書詳細(xì)論述了我產(chǎn)生“資源鎖”的原始動機和想法,這個模板主要就是基于“資源鎖”在開發(fā),這個思路目前我起碼沒有看到有其他人有過,從思路傳承性上,我證明哈,這個東東是我的。呵呵。 文中代碼很簡單,大家只要把核心的模板代碼拷貝下來,放到一個xgvar.h的頭文件里面,就可以用,當(dāng)然也可以是你喜歡的其他名字啦。不過注意啊,這個模板代碼,在Windwos下可以使用,Linux下是不可以的,請關(guān)注,別用錯了。 ========================================================= 多線程的變量同步問題,一直是困擾廣大VC程序員的一大難題,其主要表現(xiàn)是在多線程模式下,線程間共享變量的存取不再安全,程序員無法確保變量的值在存取時是否準(zhǔn)確可信,對此,微軟給出的解決方案是使用臨界區(qū)對象加以保護。但是,臨界區(qū)對象使用太過于繁瑣,需要不斷地加鎖和解鎖,很容易搞忘,引起新的Bug。 這里,東樓給出多線程安全的變量模板,由此模板,可派生絕大多數(shù)變量類型,實現(xiàn)線程間各種變量的安全互訪。本模板已經(jīng)重載了幾乎全部運算符,大家可以很方便地使用++、――、+=、-=等操作,方便編程使用。 #ifndef _XiaoGeMVarTempleteHasBeenDefined_ #define _XiaoGeMVarTempleteHasBeenDefined_ #include <Afxmt.h> template <class MVAR_TYPE> class MVAR { public: MVAR() { m_pBegin=new char[sizeof(MVAR_TYPE)]; memset(m_pBegin,0,sizeof(MVAR_TYPE)); } ~MVAR(){delete[] m_pBegin;} int GetLength(){return sizeof(MVAR_TYPE);} MVAR_TYPE Set(MVAR_TYPE& value) { m_csLockHandle.Lock(); memcpy(m_pBegin,(char*)&value,sizeof(MVAR_TYPE)); m_csLockHandle.Unlock(); return value; } MVAR_TYPE Get() { MVAR_TYPE myValue; m_csLockHandle.Lock(); memcpy((char*)&myValue,m_pBegin,sizeof(MVAR_TYPE)); m_csLockHandle.Unlock(); return myValue; } MVAR_TYPE operator=(MVAR_TYPE value) { MVAR_TYPE myValue; m_csLockHandle.Lock(); myValue=value; memcpy(m_pBegin,(char*)&myValue,sizeof(MVAR_TYPE)); m_csLockHandle.Unlock(); return myValue; } MVAR_TYPE operator~() { MVAR_TYPE myValue; m_csLockHandle.Lock(); memcpy((char*)&myValue,m_pBegin,sizeof(MVAR_TYPE)); myValue=~myValue; m_csLockHandle.Unlock(); return myValue; } MVAR_TYPE operator++(int) { MVAR_TYPE myValue; m_csLockHandle.Lock(); memcpy((char*)&myValue,m_pBegin,sizeof(MVAR_TYPE)); myValue++; memcpy(m_pBegin,(char*)&myValue,sizeof(MVAR_TYPE)); m_csLockHandle.Unlock(); return myValue; } MVAR_TYPE operator++() { MVAR_TYPE myValue; m_csLockHandle.Lock(); memcpy((char*)&myValue,m_pBegin,sizeof(MVAR_TYPE)); myValue++; memcpy(m_pBegin,(char*)&myValue,sizeof(MVAR_TYPE)); m_csLockHandle.Unlock(); return myValue; } MVAR_TYPE operator--(int) { MVAR_TYPE myValue; m_csLockHandle.Lock(); memcpy((char*)&myValue,m_pBegin,sizeof(MVAR_TYPE)); myValue--; memcpy(m_pBegin,(char*)&myValue,sizeof(MVAR_TYPE)); m_csLockHandle.Unlock(); return myValue; } MVAR_TYPE operator--() { MVAR_TYPE myValue; m_csLockHandle.Lock(); memcpy((char*)&myValue,m_pBegin,sizeof(MVAR_TYPE)); myValue--; memcpy(m_pBegin,(char*)&myValue,sizeof(MVAR_TYPE)); m_csLockHandle.Unlock(); return myValue; } MVAR_TYPE operator+(MVAR_TYPE value) { MVAR_TYPE myValue; m_csLockHandle.Lock(); memcpy((char*)&myValue,m_pBegin,sizeof(MVAR_TYPE)); myValue+=value; m_csLockHandle.Unlock(); return myValue; } MVAR_TYPE operator-(MVAR_TYPE value) { MVAR_TYPE myValue; m_csLockHandle.Lock(); memcpy((char*)&myValue,m_pBegin,sizeof(MVAR_TYPE)); myValue-=value; m_csLockHandle.Unlock(); return myValue; } MVAR_TYPE operator*(MVAR_TYPE value) { MVAR_TYPE myValue; m_csLockHandle.Lock(); memcpy((char*)&myValue,m_pBegin,sizeof(MVAR_TYPE)); myValue*=value; m_csLockHandle.Unlock(); return myValue; } MVAR_TYPE operator/(MVAR_TYPE value) { MVAR_TYPE myValue; m_csLockHandle.Lock(); memcpy((char*)&myValue,m_pBegin,sizeof(MVAR_TYPE)); myValue/=value; m_csLockHandle.Unlock(); return myValue; } MVAR_TYPE operator&(MVAR_TYPE value) { MVAR_TYPE myValue; m_csLockHandle.Lock(); memcpy((char*)&myValue,m_pBegin,sizeof(MVAR_TYPE)); myValue&=value; m_csLockHandle.Unlock(); return myValue; } MVAR_TYPE operator|(MVAR_TYPE value) { MVAR_TYPE myValue; m_csLockHandle.Lock(); memcpy((char*)&myValue,m_pBegin,sizeof(MVAR_TYPE)); myValue|=value; m_csLockHandle.Unlock(); return myValue; } MVAR_TYPE operator^(MVAR_TYPE value) { MVAR_TYPE myValue; m_csLockHandle.Lock(); memcpy((char*)&myValue,m_pBegin,sizeof(MVAR_TYPE)); myValue^=value; m_csLockHandle.Unlock(); return myValue; } MVAR_TYPE operator+=(MVAR_TYPE value) { MVAR_TYPE myValue; m_csLockHandle.Lock(); memcpy((char*)&myValue,m_pBegin,sizeof(MVAR_TYPE)); myValue+=value; memcpy(m_pBegin,(char*)&myValue,sizeof(MVAR_TYPE)); m_csLockHandle.Unlock(); return myValue; } MVAR_TYPE operator-=(MVAR_TYPE value) { MVAR_TYPE myValue; m_csLockHandle.Lock(); memcpy((char*)&myValue,m_pBegin,sizeof(MVAR_TYPE)); myValue-=value; memcpy(m_pBegin,(char*)&myValue,sizeof(MVAR_TYPE)); m_csLockHandle.Unlock(); return myValue; } MVAR_TYPE operator*=(MVAR_TYPE value) { MVAR_TYPE myValue; m_csLockHandle.Lock(); memcpy((char*)&myValue,m_pBegin,sizeof(MVAR_TYPE)); myValue*=value; memcpy(m_pBegin,(char*)&myValue,sizeof(MVAR_TYPE)); m_csLockHandle.Unlock(); return myValue; } MVAR_TYPE operator/=(MVAR_TYPE value) { MVAR_TYPE myValue; m_csLockHandle.Lock(); memcpy((char*)&myValue,m_pBegin,sizeof(MVAR_TYPE)); myValue/=value; memcpy(m_pBegin,(char*)&myValue,sizeof(MVAR_TYPE)); m_csLockHandle.Unlock(); return myValue; } MVAR_TYPE operator&=(MVAR_TYPE value) { MVAR_TYPE myValue; m_csLockHandle.Lock(); memcpy((char*)&myValue,m_pBegin,sizeof(MVAR_TYPE)); myValue&=value; memcpy(m_pBegin,(char*)&myValue,sizeof(MVAR_TYPE)); m_csLockHandle.Unlock(); return myValue; } MVAR_TYPE operator|=(MVAR_TYPE value) { MVAR_TYPE myValue; m_csLockHandle.Lock(); memcpy((char*)&myValue,m_pBegin,sizeof(MVAR_TYPE)); myValue|=value; memcpy(m_pBegin,(char*)&myValue,sizeof(MVAR_TYPE)); m_csLockHandle.Unlock(); return myValue; } MVAR_TYPE operator^=(MVAR_TYPE value) { MVAR_TYPE myValue; m_csLockHandle.Lock(); memcpy((char*)&myValue,m_pBegin,sizeof(MVAR_TYPE)); myValue^=value; memcpy(m_pBegin,(char*)&myValue,sizeof(MVAR_TYPE)); m_csLockHandle.Unlock(); return myValue; } BOOL operator>(MVAR_TYPE value) { MVAR_TYPE myValue; BOOL bRet; m_csLockHandle.Lock(); memcpy((char*)&myValue,m_pBegin,sizeof(MVAR_TYPE)); bRet=(myValue>value); m_csLockHandle.Unlock(); return bRet; } BOOL operator<(MVAR_TYPE value) { MVAR_TYPE myValue; BOOL bRet; m_csLockHandle.Lock(); memcpy((char*)&myValue,m_pBegin,sizeof(MVAR_TYPE)); bRet=(myValue<value); m_csLockHandle.Unlock(); return bRet; } BOOL operator>=(MVAR_TYPE value) { MVAR_TYPE myValue; BOOL bRet; m_csLockHandle.Lock(); memcpy((char*)&myValue,m_pBegin,sizeof(MVAR_TYPE)); bRet=(myValue>=value); m_csLockHandle.Unlock(); return bRet; } BOOL operator<=(MVAR_TYPE value) { MVAR_TYPE myValue; BOOL bRet; m_csLockHandle.Lock(); memcpy((char*)&myValue,m_pBegin,sizeof(MVAR_TYPE)); bRet=(myValue<=value); m_csLockHandle.Unlock(); return bRet; } BOOL operator==(MVAR_TYPE value) { MVAR_TYPE myValue; BOOL bRet; m_csLockHandle.Lock(); memcpy((char*)&myValue,m_pBegin,sizeof(MVAR_TYPE)); bRet=(myValue==value); m_csLockHandle.Unlock(); return bRet; } BOOL operator!=(MVAR_TYPE value) { MVAR_TYPE myValue; BOOL bRet; m_csLockHandle.Lock(); memcpy((char*)&myValue,m_pBegin,sizeof(MVAR_TYPE)); bRet=(myValue!=value); m_csLockHandle.Unlock(); return bRet; } private: char* m_pBegin; CCriticalSection m_csLockHandle; }; typedef MVAR<char>????????????? MCHAR; typedef MVAR<unsigned char>?????? MUCHAR; typedef MVAR<short>???????????? MSHORT; typedef MVAR<unsigned short>??? MUSHORT; typedef MVAR<int>?????????????? MINT; typedef MVAR<unsigned int>??????? MUINT; typedef MVAR<long>????????????? MLONG; typedef MVAR<unsigned long>?????? MULONG; typedef MVAR<float>???????????? MFLOAT; typedef MVAR<double>??????????? MDOUBLE; typedef MVAR<BOOL>????????????? MBOOL; typedef MVAR<LPVOID>??????????? MLPVOID; typedef MVAR<BYTE>????????????? MBYTE; #endif //_XiaoGeMVarTempleteHasBeenDefined_ 大家只需要把這段代碼放入Mvar.h文件,在stdafx.h中include這個頭文件,即可在程序中自由使用變量。以上僅僅是東樓根據(jù)自己的需要,派生的幾個常用類型,大家也可以嘗試派生新的類型使用。 注意,當(dāng)派生的變量需要取得其中的值時,必須使用.Get()成員函數(shù),這是唯一一點不如普通變量方便的地方。 下面給出一個控制例子,大家可以參考: #includen “mvar.h” class CMyClass { public: CMyClass(); ~ CMyClass(); protected: static UINT MyThread(LPVOID pParam);??? //線程函數(shù) MBOOL m_bThreadContinue;?????????? //線程循環(huán)標(biāo)志 MUINT m_nThreadCount;????????????? //線程計數(shù)器 }; CMyClass::CMyClass() { m_bThreadContinue=TRUE; m_nThreadCount=0; int i; //開啟100個線程 for(i=0;i<100;i++) { m_nThreadCount++;??????????????? //一定要在開啟線程前累加線程計數(shù)器 AfxBeginThread(MyThread,this);??? //開啟線程,以本對象指針為參數(shù) } } CMyClass::~CMyClass() { m_bThreadContinue=FALSE;? //通知線程關(guān)閉 while(m_nThreadCount!=0) {}?? //等待所有線程退出 //此時退出,線程已經(jīng)全部安全退出!!! } UINT CMyClass::MyThread(LPVOID pParam) { CMyClass* pThis=(CMyClass*)pParam;??? //得到本對象指針 while(pThis->m_bThreadContinue) { //循環(huán)體 Sleep(100); } pThis->m_nThreadCount --; //線程計數(shù)器減1 return 0; }? 如果有問題,歡迎大家提問,如果有Bug,也請大家及時向東樓提出。 =======================================================
在線底價購買《0bug-C/C++商用工程之道》
(直接點擊下面鏈接或拷貝到瀏覽器地址欄)
http://s.click.taobao.com/t_3?&p=mm_13866629_0_0&n=23&l=http%3A%2F%2Fsearch8.taobao.com%2Fbrowse%2F0%2Fn-g%2Corvv64tborsvwmjvgawdkmbqgboq---g%2Cgaqge5lhebbs6qzlfmqmttgtyo42jm6m22xllqa-------------1%2C2%2C3%2C4%2C5%2C6%2C7%2C8%2C9%2C10%2C11%2C12%2C13%2C14%2C15%2C16%2C17%2C18%2C19%2C20---40--coefp-0-all-0.htm%3Fpid%3Dmm_13866629_0_0
肖舸
在線底價購買《0bug-C/C++商用工程之道》
(直接點擊下面鏈接或拷貝到瀏覽器地址欄)
http://s.click.taobao.com/t_3?&p=mm_13866629_0_0&n=23&l=http%3A%2F%2Fsearch8.taobao.com%2Fbrowse%2F0%2Fn-g%2Corvv64tborsvwmjvgawdkmbqgboq---g%2Cgaqge5lhebbs6qzlfmqmttgtyo42jm6m22xllqa-------------1%2C2%2C3%2C4%2C5%2C6%2C7%2C8%2C9%2C10%2C11%2C12%2C13%2C14%2C15%2C16%2C17%2C18%2C19%2C20---40--coefp-0-all-0.htm%3Fpid%3Dmm_13866629_0_0
肖舸
轉(zhuǎn)載于:https://blog.51cto.com/tonyxiaohome/255366
總結(jié)
以上是生活随笔為你收集整理的多年以后重发:多线程安全的变量模板的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 北大青鸟组建与维护企业网络高级技术PPT
- 下一篇: SQL SERVER重置自动编号列(标识