OnTheWay2012
埋葬昨天的我,迎來重生的我!
C++博客
首頁
新文章
新隨筆
聚合
管理
posts - 15, comments - 89, trackbacks - 0
一種線程安全的單例模式實現方式
昨天寫了一篇隨筆,里面提到了單例模式,本來沒有想多說單例模式,可是有人回復說讓我先看看線程安全再來談設計模式。
今天閑來無事就隨便寫了個線程安全的設計模式,具體代碼如下:
1
#include
<
iostream
>
2
#include
<
vector
>
3
#include
<
bitset
>
4
#include
<
assert.h
>
5
#include
<
Windows.h
>
6
#include
<
process.h
>
7
8
using
namespace
std;
9
10
class
CSingleton
11
{
12
private
:
13
class
CAssistForSingleton
14
{
15
private
:
16
CRITICAL_SECTION m_cs;
17
18
public
:
19
CAssistForSingleton()
20
{
21
InitializeCriticalSection(
&
m_cs);
22
}
23
24
~
CAssistForSingleton()
25
{
26
DeleteCriticalSection(
&
m_cs);
27
}
28
29
public
:
30
void
Lock()
31
{
32
EnterCriticalSection(
&
m_cs);
33
}
34
35
void
UnLock()
36
{
37
LeaveCriticalSection(
&
m_cs);
38
}
39
}
;
40
41
private
:
42
static
CAssistForSingleton m_refSycObj;
43
static
CSingleton
*
m_pInstance;
44
45
static
int
m_nData;
46
47
private
:
48
CSingleton()
49
{
50
51
}
52
53
public
:
54
static
CSingleton
*
GetInstatnce()
55
{
56
m_refSycObj.Lock();
57
if
(NULL
==
m_pInstance)
58
{
59
m_pInstance
=
new
CSingleton;
60
cout
<<
"
new CSingleton
"
<<
endl;
61
}
62
m_refSycObj.UnLock();
63
64
return
m_pInstance;
65
}
66
67
public
:
68
static
int
GetData()
69
{
70
return
m_nData;
71
}
72
73
static
void
SetData(
int
nData)
74
{
75
m_refSycObj.Lock();
76
m_nData
=
nData;
77
m_refSycObj.UnLock();
78
}
79
}
;
80
81
CSingleton::CAssistForSingleton CSingleton::m_refSycObj
=
CSingleton::CAssistForSingleton();
82
CSingleton
*
CSingleton::m_pInstance
=
NULL;
83
int
CSingleton::m_nData
=
0
;
84
85
unsigned
int
WINAPI ThreadFun(
void
*
)
86
{
87
cout
<<
"
Launcher Thread
"
<<
endl;
88
89
for
(
int
i
=
0
; i
<
99999999
; i
++
)
90
{
91
CSingleton
*
pSingl
=
CSingleton::GetInstatnce();
92
if
(NULL
!=
pSingl)
93
{
94
pSingl
->
SetData(i);
95
}
96
97
Sleep(
500
);
98
}
99
100
return
0
;
101
}
102
103
int
main(
int
argv,
char
*
argc[])
104
{
105
uintptr_t HandleThread[
10
];
106
unsigned
int
nThreadId
=
0
;
107
for
(
int
i
=
0
; i
<
10
; i
++
)
108
{
109
HandleThread[i]
=
_beginthreadex(NULL,
0
, ThreadFun, NULL,
0
,
&
nThreadId);
110
}
111
112
WaitForMultipleObjects(
10
, (
const
HANDLE
*
)HandleThread, TRUE, INFINITE);
113
114
return
0
;
115
}
116
117
以上就是我的實現,有什么問題歡迎批評指針。
posted on 2010-05-21 09:52
OnTheWay
閱讀(5748)
評論(15)
編輯
收藏
引用
所屬分類:
軟件設計
FeedBack:
#
re: 一種線程安全的單例模式實現方式
2010-05-21 10:15 |
戰魂小筑
1. 可以不用單件, 程序開始時全局new出來, 以后不用鎖,直接用就好.
2. 既然全是靜態數據, 還需要用Singleton呢?
3. 用Interlock會更高效
回復
更多評論
#
re: 一種線程安全的單例模式實現方式
2010-05-21 10:52 |
GunsNRose
之前看過一個,建議將構造弄成 私有的,生成實例由 GetInstatnce來做
別人new是new不了的
回復
更多評論
#
re: 一種線程安全的單例模式實現方式
2010-05-21 15:37 |
OwnWaterloo
依然不是線程安全的。
回復
更多評論
#
re: 一種線程安全的單例模式實現方式
2010-05-21 21:02 |
ccsdu2009
去看看ZThread中的單件吧
以前的話我會推薦loki的
但是現在歸納絕那個太復雜了
回復
更多評論
#
re: 一種線程安全的單例模式實現方式[未登錄]
2010-05-22 07:17 |
OnTheWay
@OwnWaterloo
您好,首先感謝您對本隨筆的關注。懇請您說詳細一點,我不太明白哪些地方還不是線程安全的。
回復
更多評論
#
re: 一種線程安全的單例模式實現方式
2010-05-22 08:57 |
OwnWaterloo
@OnTheWay
class S
{
S() { ... }
~S(); { ... }
S(S const&);
S& operator=(S const&S);
public:
static S& instance()
{
static S s;
return s;
}
};
你認為C++(C++03)是否保證S::instance是線程安全的?
如果是, 請說明理由。
如果C++不保證, 是否應該將S::instance作成線程安全的?
回復
更多評論
#
re: 一種線程安全的單例模式實現方式
2010-05-22 09:00 |
OwnWaterloo
@OnTheWay
再來一種:
class S
{
// ctor, copy, dtor, assignment
static S s_;
public:
S& instance() { return s_; }
};
S S::s_;
同樣是上面的問題。
回復
更多評論
#
re: 一種線程安全的單例模式實現方式[未登錄]
2010-05-22 09:12 |
OnTheWay
@OwnWaterloo
我覺得不是線程安全的,原因如下:
在你給出的代碼中類S中的函數(雖然現在我還沒有想不出這種函數)可能不是線程安全的。
我的MSN是wwj_5_209@163.com,能否加我一下,我們討論一下。
回復
更多評論
#
re: 一種線程安全的單例模式實現方式
2010-05-22 14:59 |
匿名
@OwnWaterloo
與博文中的不是一回事。
回復
更多評論
#
re: 一種線程安全的單例模式實現方式
2010-05-22 19:08 |
OwnWaterloo
@OnTheWay
注意兩種需要運行時初始化的靜態對象, s和s_。
前者的初始化時機C++有保證, 但不保證多線程安全。
后者的初始化時機C++只保證同一翻譯單元內中有順序。
再看static CAssistForSingleton m_refSycObj;
這就屬于第2種。
下面的情況有發生的可能性:
1. 另一翻譯單元的靜態對象先于m_refSycObj被初始化
2. 在它初始化時訪問了CSingleton *GetInstatnce()
此時就訪問了一個"未初始化"的臨界區。
這已經是bug。
再有, 如果有下列情況:
1. 一些先于m_refSycObj初始化的代碼開啟了線程
2. 多個線程在m_refSycObj初始化前訪問CSingleton *GetInstatnce()
一個未初始化的m_refSycObj根本不能用于同步。
所以, 上面的第1個問題: 這樣做不是多線程安全的。
而靜態對象在構造時啟動線程的情況并不多, 所以并不一定需要將s_作成多線程安全。
例如boost就是這樣, 要求在進入main之前, 是不許有兩條以上的執行路徑去訪問。
這就是第2個問題。
如果需要完全的多線程安全:
1. 使用once_initial函數(pthread或者win6有提供)
2. 使用"可以靜態初始化"的鎖, 比如pthread_mutex_t就可以
或者自己使用一個spinlock也行。
我沒有msn…… 用gmail的同名郵箱。
回復
更多評論
#
re: 一種線程安全的單例模式實現方式
2010-05-22 19:09 |
OwnWaterloo
@匿名
知道什么叫"舉一反三"嗎?
回復
更多評論
#
re: 一種線程安全的單例模式實現方式[未登錄]
2010-05-22 22:50 |
~
個人一點隨想:我覺得應該從實際應用的邏輯上來進行線程安全的分析,并根據現實情況的分析避免不必要的加解鎖操作。某些代碼只是一種理想化的東西。現實中有太多比SetData復雜的邏輯。而且也不一定需要加鎖。當然從你這個代碼看,GetInstatnce當然是正確的哈。
回復
更多評論
#
re: 一種線程安全的單例模式實現方式
2010-05-27 00:02 |
GunsNRose
傻逼實現也好意思貼出來?丟人現眼
回復
更多評論
#
re: 一種線程安全的單例模式實現方式[未登錄]
2010-05-27 08:56 |
cppexplore
@OnTheWay
c++里的線程安全單例應該是典型的雙重檢測.
文中如此實現的話, 每次調用GetInstatnce都要涉及到加鎖操作, 估計沒人愿意調用.
回復
更多評論
#
re: 一種線程安全的單例模式實現方式
2010-10-30 14:27 |
楊云召
沒有用volatile,顯然不是線程安全的
回復
更多評論
刷新評論列表
只有注冊用戶
登錄
后才能發表評論。
【推薦】100%開源!大型工業跨平臺軟件C++源碼提供,建模,組態!
網站導航:
博客園
IT新聞
BlogJava
博問
Chat2DB
管理
<
2025年5月
>
日
一
二
三
四
五
六
27
28
29
30
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
5
6
7
常用鏈接
我的隨筆
我的評論
我參與的隨筆
留言簿
(4)
給我留言
查看公開留言
查看私人留言
隨筆分類
C、C++(2)
操作系統(Windows、Linux、Unix)
讀書筆記
個人感悟(4)
面經 (4)
軟件設計(1)
數據庫
算法(3)
線程、進程
英語
雜項
轉載
隨筆檔案
2011年1月 (1)
2010年12月 (2)
2010年11月 (1)
2010年6月 (1)
2010年5月 (6)
2010年4月 (1)
2010年3月 (3)
友情連接
搜索
最新評論
1.?re: 對“隨筆”所寫的一篇文章《鏈表實驗》的一點看法
評論內容較長,點擊標題查看
--陳梓瀚(vczh)
2.?re: 對“隨筆”所寫的一篇文章《鏈表實驗》的一點看法
謝謝咯,呵呵。我喜歡這代碼風格,向你學習
--あ維wêiセ
3.?re: 一種基于引用計數機制的智能指針實現
把A *p = new A();這句換成A p;不行嗎?
--叫我老王吧
4.?re: 一種基于引用計數機制的智能指針實現
Boost 里面有,在C++ TR1 里面也已經有這種指針(就是來自Boost)
--Phuehvk
5.?re: 一種基于引用計數機制的智能指針實現[未登錄]
比較討厭這種引用計數指針的使用,一旦使用就意味這在所有的函數參數中必須使用指針引用或者值拷貝,一旦某些函數要求用裸指針,就可能引發問題。
--hdqqq
閱讀排行榜
1.?一道面試題(求一個unsigned int 數的二進制表示中有多少個1?)(6159)
2.?一種線程安全的單例模式實現方式(5748)
3.?一種基于引用計數機制的智能指針實現(2918)
4.?不要把類的外衣脫下來,讓類的美麗消失于無形(2781)
5.?幾道面試題,有的做出來了,有的不會做,請大家指教(2618)
評論排行榜
1.?一道面試題(求一個unsigned int 數的二進制表示中有多少個1?)(15)
2.?一種線程安全的單例模式實現方式(15)
3.?幾道面試題,有的做出來了,有的不會做,請大家指教(14)
4.?令人氣憤的現象(13)
5.?不要把類的外衣脫下來,讓類的美麗消失于無形(9)
Copyright ©2025 OnTheWay Powered By
博客園
模板提供:
滬江博客
免费久久人人爽人人爽av
|
久久最新免费视频
|
天天爽天天狠久久久综合麻豆
|
久久婷婷色综合一区二区
|
色综合久久久久久久久五月
|
久久久久人妻一区精品色
|
丁香狠狠色婷婷久久综合
|
久久精品国产精品亚洲人人
|
久久午夜福利电影
|
久久精品无码专区免费东京热
|
久久久久综合网久久
|
亚洲精品第一综合99久久
|
蜜臀av性久久久久蜜臀aⅴ麻豆
|
99久久国产综合精品麻豆
|
久久人人爽人人爽人人片AV麻豆
|
久久久久亚洲AV成人片
|
久久福利青草精品资源站
|
香蕉久久夜色精品国产2020
|
777米奇久久最新地址
|
亚洲国产精品无码久久青草
|
久久AV无码精品人妻糸列
|
国产免费久久精品丫丫
|
久久永久免费人妻精品下载
|
久久久久婷婷
|
久久er热视频在这里精品
|
99蜜桃臀久久久欧美精品网站
|
伊人色综合久久天天
|
久久精品中文闷骚内射
|
亚洲成色WWW久久网站
|
亚洲欧美久久久久9999
|
久久精品国产72国产精福利
|
国产欧美久久一区二区
|
久久99精品久久久大学生
|
一级a性色生活片久久无少妇一级婬片免费放
|
久久综合给久久狠狠97色
|
久久成人小视频
|
国产一区二区久久久
|
伊人 久久 精品
|
国产精品亚洲综合久久
|
久久国产精品久久久
|
亚洲色大成网站WWW久久九九
|