青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

posts - 297,  comments - 15,  trackbacks - 0
出處 http://www.shnenglu.com/cexer/archive/2008/07/08/55670.html

  單件(Singelton)模式可以說是眾多設計模式當中,理解起來最容易,概念最為簡單的一個。并且在實際的設計當中也是使用得又最為頻繁 的,甚至有很多其它的模式都要借助單件才能更好地實現。然而就是這樣被強烈需求的“一句話模式”(一句話就能闡述明白),雖然有無數的牛人浸淫其中,至今 也沒有誰鼓搗出一個完美的實現。我小菜鳥一只自然更不敢逢人便談單件。不過這個貼的主題是跟單件模式是密不可分的。

  什么又叫做“線程相關的單件模式”呢?也許你已經顧名思義猜出了八九分。不過還是允許我簡單地用實例說明一下。

  假設你要設計了一個簡單的 GUI 框架,這個框架當中需要這樣一個全局變量(單件模式),它保存了所有窗口句柄與窗口指針的映射(我見過的數個的開源 GUI 框架都有類似的東西。)。在 WIN32 平臺上就是這樣一個簡單的東西:

    //窗口的包裝類
class Window
{
HWND m_hwnd;
public:
bool create();
bool destroy();

//其它細節
};

//窗口句柄與其對象指針的映射
typedef map<HWND,Window*> WindowMap;
typedef WindowMap::iterator WindowIter;
WindowMap theWindowMap;




  每創建一個窗口,就需要往這個 theWindowMap 當中添加映射。每銷毀一個窗口,則需要從其中刪除掉相關映射。實現代碼類似:

    //創建窗口
bool Window::create()
{
m_hwnd=::CreateWindow(/*參數略*/);
if(!::IsWindow(m_hwnd))
return false;

theWindowMap[m_hwnd]=this; //添加映射
return true;
}

//銷毀窗口
bool Window::destroy()
{
::DestroyWindow(m_hwnd);

theWindowMap.erase(m_hwnd); //刪除映射
return true;
}


  你可以用任何可能的單件模式來實現這樣一個全局變量 theWindowMap,它會 工作得很好。但是當如果考慮要給程序添加多線程支持(“多線程”是如此麻煩,它總愛和“但是”一起出現,給本來進行得很順利的事情引起波折。),就會發現 此時也許純粹的單件模式并不是最好的選擇。例如一個線程同時創建窗口,那么兩個線程同時調用:

    theWindowMap[m_hwnd]=this;


  這顯然不是一個原子操作,可以肯定如果你堅持這樣干你的程序會慢慢走向崩潰,幸運一點只是程序運行結果錯誤,如果你恰好那幾天印堂發暗面色發灰,說不定就因為這小小的錯誤,被無良的BOSS作為借口開除掉了,那可是個悲慘的結局。

  當然大多數的單件模式已經考慮到了多線程的問題。它們的解決方案就是給加上線程鎖 ,我在數個開源的 GUI 框架看到他們都采用了這種解決方案。不過這樣做,在線程同步過程當中,會產生與 GUI 框架邏輯不相關的同步消耗,雖然不是什么大不了的消耗,但是客戶可能因此就選擇了你的竟爭對手,如果線程竟爭激烈,在強烈渴求資源的環境(如小型移動設 置)當中,這種消耗更是不可忽視的。

  實際上在應用當中,極少有線程需要插入刪除其它線程創建的窗口映射(如果確實有這種需要,那么可以肯定項目的設計上出了問題)。在這種情況下本 線程創建窗口映射都將只是本線程存取,類似“Thread-Specific”的概念。也就是說,theWindowMap 當中其它線程創建的窗口的映射對于本線程來說都是不需關心的,我們卻要為那部分不必要東西整天提心吊膽并付出運行時消耗的代價,這也有點像“穿著棉襖洗 澡”。但是怎么樣才能做到更輕松爽快些呢?

  就本例問題而言,我們需要這樣一種變量來保存窗口映射,它針對每個線程有不同的值(Thread-Specific Data),這些值互不影響,并且所有線程對它的訪問如同是在訪問一個進程內的全局變量(Singelton)。

  如果你是熟悉多線程編程的人,那么“Thread-Specific ”一定讓你想起了什么。是的,“Thread-Specific Storage ” (線程相關存存諸,簡稱 TSS ),正是我們需要的,這是大多數操作系統都提供了的一種線程公共資源安全機制,這種機制允許以一定方式創建一個變量,這個變量在所在進程當中的每個線程當 中,可以擁有不同的值。在 WIN32 上,這個變量就稱為“索引”,其相關的值則稱為“槽”, “Thread-Local Storage”(線程局部存諸,簡稱 TLS )機制。它的提了供這樣幾個函數來定義,設置,讀取線程相關數據(關于 TLS 的更多信息,可以查閱 MSDN ):

    //申請一個“槽”的索引。
DWORD TlsAlloc( void );

//獲得調用線程當中指定“槽”的值。
VOID* TlsGetValue( DWORD dwTlsIndex );

//設置調用線程當中指定“槽”的值。
BOOL TlsSetValue( DWORD dwTlsIndex,VOID* lpTlsValue );

//釋放掉申請的“槽”的索引
BOOL TlsFree( DWORD dwTlsIndex );

  具體使用流程方法:先調用 TlsAlloc 申請一個“索引”,然后線程在適當時機創建一個對象并調用 TlsSetValue 將“索引”對應的“槽”設置為該對象的指針,在此之后即可用 TlsGetValue 訪問該“糟”。最后在不需要的時候調用 TlsFree ,如在本例當中,調用 TlsFree 的最佳時機是在進程結束時。

  先封裝一下 TlsAlloc 和 TlsFree  以方便對 ”索引“的管理。

    class TlsIndex
{
public:
TlsIndex()
:m_index(::TlsAlloc())
{}

~TlsIndex()
{
::TlsFree(m_index);
}

public:
operator DWORD() const
{
return m_index;
}

private:
DWORD m_index;
};

  
  如你所見,類 TlsIndex 將在構造的時候申請一個“索引”,在析構的時候釋放此“索引”。

  在本例當中 TlsIndex 的對象應該存在進程的生命周內,以保證在進程退出之前,這個“索引”都不會被釋放,這樣的 TlsIndex 對象聽起來正像一個全局靜態對象,不過 Meyers Singelton (用函數內的靜態對象實現)在這里會更適合,因為我們不需要對這個對象的生命周末進行精確控制,只需要它在需要的時候創建,然后在進程結束前銷毀即可。這 種方式只需要很少的代碼即可實現,比如:

    DWORD windowMapTlsIndex()
{
static TlsIndex s_ti;  //提供自動管理生命周期的“索引”
return s_ti;
}


  利用這個“索引”,我們就能實現上述“Thread-Specific”的功能:

    WindowMap* windowMap()
{
WindowMap* wp=reinterpret_cast<WindowMap*>(::TlsGetValue(windowMapTlsIndex()));
if(!wp)
{
wp=new WindowMap();
::TlsSetValue(windowMapTlsIndex(),wp);
}
return wp;
}

#define theWindowMap *(windowMap())

  
  注意各線程訪問以上的代碼不會存在竟爭。這樣就實現了一個線程安全且無線程同步消耗版本的“全局對象” theWindowMap 。我們甚至不用改變Window::create,Window::destory,queryWindow 的代碼,

  這幾個簡單的函數看起來似乎不像一個“模式”,但是它確實是的。

  現在總結一下“線程相關的單件模式”的概念:保證一個類在一個線程當中只有一個實例,并提供一個訪問它的線程內的訪問點的模式。

  為了不重復地制造車輪,我將此類應用的模式封裝了一下:

    template<typename TDerived>
class TlsSingelton
{
typedef TDerived _Derived;
typedef TlsSingelton<TDerived> _Base;

public:
static _Derived* tlsInstance()
{
return tlsCreate();
}

protected:
static _Derived* tlsCreate()
{
_Derived* derived=tlsGet();
if(derived)
return derived;

derived=new _Derived();
if(derived && TRUE==::TlsSetValue(tlsIndex(),derived))
return derived;

if(derived)
delete derived;

return NULL;
}

static bool tlsDestroy()
{
_Derived* derived=tlsGet();
if(!derived)
return false;

delete derived;
return true;
}

static DWORD tlsIndex()
{
static TlsIndex s_tlsIndex;
return s_tlsIndex;
}

private:
static _Derived* tlsGet()
{
return reinterpret_cast<_Derived*>(::TlsGetValue(tlsIndex()));
}

static bool tlsSet(_Derived* derived)
{
return TRUE==::TlsSetValue(tlsIndex(),derived);
}

//noncopyable
private:
TlsSingelton(const _Base&);
TlsSingelton& operator=(const _Base&);
};


  將 tlsCreate,tlsDestroy 兩個函數設置為保護成員,是為了防止一些不三不四吊爾啷噹的程序隨意地刪除。

  示例:

    class WindowMapImpl:public TlsSingelton<WindowMap>
{
WindowMap m_map;
public:
WidnowMap& theWindowMapImpl()
{
return m_map;
}

public:
~WindowMapImpl();

protected:
WindowMapImpl(); //只能通過tlsCreate創建
friend class _Base;
};

#define theWindowMap (WindowMapImpl::tlsInstance()->theWindowMapImpl())



  仍不需要修改原有窗口代碼。

posted on 2008-07-20 17:28 chatler 閱讀(134) 評論(0)  編輯 收藏 引用

只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


<2010年11月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

常用鏈接

留言簿(10)

隨筆分類(307)

隨筆檔案(297)

algorithm

Books_Free_Online

C++

database

Linux

Linux shell

linux socket

misce

  • cloudward
  • 感覺這個博客還是不錯,雖然做的東西和我不大相關,覺得看看還是有好處的

network

OSS

  • Google Android
  • Android is a software stack for mobile devices that includes an operating system, middleware and key applications. This early look at the Android SDK provides the tools and APIs necessary to begin developing applications on the Android platform using the Java programming language.
  • os161 file list

overall

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            国产欧美日韩不卡免费| 最新亚洲电影| 久久精品国产精品亚洲综合 | 亚洲国产精品尤物yw在线观看| 久久精品国产成人| 久久久国际精品| 亚洲精品国产品国语在线app | 久久久久久国产精品mv| 久久av一区| 亚洲人午夜精品| 一区二区三区日韩欧美精品| 国产精品私人影院| 久久久久久亚洲精品中文字幕| 欧美在线视频观看免费网站| 亚洲国产欧美在线| 亚洲性感美女99在线| 国产一区二区三区自拍| 亚洲国产高清一区| 欧美午夜国产| 免费一级欧美在线大片| 欧美日本一区二区三区| 欧美制服丝袜第一页| 欧美成人69av| 久久九九免费视频| 欧美国产精品| 久久久久久久网站| 欧美伦理视频网站| 久久久www成人免费毛片麻豆| 嫩草国产精品入口| 欧美一区激情| 欧美精选一区| 久久综合久色欧美综合狠狠| 欧美片在线播放| 久久一本综合频道| 国产精品白丝av嫩草影院| 男人的天堂亚洲在线| 国产精品永久免费观看| 亚洲国产美女| 在线成人激情视频| 亚洲主播在线观看| 一区二区三区你懂的| 久久男女视频| 久久av在线看| 国产精品腿扒开做爽爽爽挤奶网站| 欧美国产高潮xxxx1819| 国产主播精品| 亚洲一区尤物| 亚洲已满18点击进入久久| 美日韩免费视频| 久久蜜桃资源一区二区老牛| 国产精品乱码一区二三区小蝌蚪| 亚洲人成人99网站| 亚洲国产精品一区二区www在线| 性欧美8khd高清极品| 亚洲欧美日韩一区在线观看| 欧美日韩情趣电影| 亚洲精品欧美精品| 日韩视频免费观看高清完整版| 久热精品视频在线免费观看| 久久天天躁夜夜躁狠狠躁2022| 国产欧美1区2区3区| 午夜精品久久久久久久白皮肤 | 国产一区深夜福利| 亚洲欧美另类国产| 欧美一级成年大片在线观看| 国产精品丝袜白浆摸在线| 亚洲性视频网址| 欧美亚洲三区| 国产一区二区久久| 久久久五月天| 亚洲丁香婷深爱综合| 日韩视频在线观看| 欧美日韩不卡一区| 在线视频欧美一区| 欧美一级视频精品观看| 国产亚洲福利| 久久久久国色av免费看影院| 欧美不卡视频| 亚洲美女精品一区| 国产精品久久久久免费a∨大胸| 中文在线不卡视频| 欧美在线播放| 亚洲第一精品久久忘忧草社区| 美女黄网久久| aaa亚洲精品一二三区| 午夜精品福利在线观看| 国产主播喷水一区二区| 免费美女久久99| 99视频有精品| 久久久久久久久久久一区| 亚洲电影在线看| 欧美日韩一区二区在线| 午夜亚洲福利在线老司机| 欧美+日本+国产+在线a∨观看| 最新高清无码专区| 国产精品扒开腿做爽爽爽软件| 欧美在线网址| 亚洲免费观看在线视频| 久久久国产午夜精品| 亚洲精品日产精品乱码不卡| 欧美午夜精品久久久久久人妖| 久久精品国产亚洲一区二区| 亚洲欧洲久久| 久久资源在线| 亚洲香蕉网站| 亚洲国产精品悠悠久久琪琪| 国产精品久久久久7777婷婷| 久久三级视频| 亚洲一区二区三区视频| 亚洲国产成人在线播放| 久久久国产亚洲精品| 亚洲性夜色噜噜噜7777| 亚洲福利在线观看| 国产伦精品一区二区三区照片91| 欧美黄色成人网| 久久看片网站| 午夜在线播放视频欧美| 日韩写真在线| 亚洲黄色毛片| 美女网站久久| 久久久中精品2020中文| 亚洲欧美国产毛片在线| 日韩视频在线免费观看| 伊人天天综合| 国内成人精品2018免费看 | 欧美大片va欧美在线播放| 午夜激情一区| 亚洲免费伊人电影在线观看av| 亚洲精品在线一区二区| 亚洲高清不卡在线| 欧美黄污视频| 欧美3dxxxxhd| 免费成人高清| 蜜臀久久99精品久久久久久9 | 欧美一级视频免费在线观看| 在线亚洲精品福利网址导航| 亚洲乱码久久| 亚洲精品网站在线播放gif| 亚洲国产清纯| 亚洲国产精品va在线观看黑人| 欧美二区不卡| 亚洲国产欧美一区二区三区同亚洲| 免费在线成人av| 免费久久99精品国产| 男人的天堂亚洲在线| 免费日韩一区二区| 欧美黄在线观看| 亚洲激情视频在线| 亚洲理论在线| 夜夜爽av福利精品导航| 亚洲午夜电影在线观看| 亚洲欧美日韩视频二区| 欧美一区二区三区婷婷月色 | 亚洲综合清纯丝袜自拍| 亚洲欧美日韩在线高清直播| 性色一区二区| 久久久美女艺术照精彩视频福利播放| 久久精品亚洲精品| 欧美+亚洲+精品+三区| 欧美日韩国产精品 | 久久久国产午夜精品| 久久一区二区精品| 欧美精品v国产精品v日韩精品| 欧美极品在线观看| 国产精品久久一卡二卡| 国产主播一区二区三区| 亚洲激情视频网| 亚洲综合精品自拍| 久久精品一级爱片| 亚洲国产精品一区二区第四页av | 久久精品一本| 欧美大片18| 国产日韩欧美在线看| 亚洲二区在线观看| 亚洲一区二区三区在线观看视频| 久久精品视频va| 亚洲电影自拍| 亚洲欧美日韩综合一区| 麻豆免费精品视频| 国产精品视频内| 亚洲激情另类| 久久精品人人做人人爽| 99在线精品视频| 亚洲在线一区二区| 久久精品电影| 欧美午夜视频| 亚洲福利电影| 欧美主播一区二区三区| 亚洲国产精品免费| 欧美一区二区日韩| 欧美视频在线一区二区三区| 精品不卡在线| 午夜精品亚洲一区二区三区嫩草| 欧美激情精品久久久久久黑人| 亚洲欧美制服中文字幕| 欧美精品www| 亚洲国产一二三| 久久综合999| 欧美一区二区三区在线观看视频 | 欧美成人精品一区二区|