演示文稿主題怎么設(shè)置啊(怎么將演示文稿主題設(shè)置)
752
2025-04-03
文章目錄
前言
享元模式與池技術(shù)
享元模式定義與結(jié)構(gòu)
線程池
對象池類圖
對象池代碼實現(xiàn)
前言
之前寫“橋接模式”的時候,說“橋接模式”是最抽象的設(shè)計模式,那是因為我沒接觸到“享元模式”。
可能橋接模式是最抽象的設(shè)計模式,但是享元模式我覺得是最煩的設(shè)計模式了。
因為這個模式和“
池技術(shù)
”有著
密不可分
的聯(lián)系。
享元模式與池技術(shù)
說到享元模式,第一個想到的應(yīng)該就是池技術(shù)了,String常量池、數(shù)據(jù)庫連接池、緩沖池、線程池等等都是享元模式的應(yīng)用,所以說享元模式是池技術(shù)和池技術(shù)密不可分。
面向?qū)ο蠹夹g(shù)可以很好地解決一些靈活性或可擴展性問題,但在很多情況下需要在系統(tǒng)中增加類和對象的個數(shù)。當(dāng)對象數(shù)量太多時,將導(dǎo)致運行代價過高,帶來性能下降等問題。享元模式正是為解決這一類問題而誕生的。享元模式通過共享技術(shù)實現(xiàn)相同或相似對象的重用。
享元模式定義與結(jié)構(gòu)
享元模式(Flyweight Pattern):運用共享技術(shù)有效地支持大量細粒度對象的復(fù)用。系統(tǒng)只使用少量的對象,而這些對象都很相似,狀態(tài)變化很小,可以實現(xiàn)對象的多次復(fù)用。由于 享元模式要求能夠共享的對象必須是細粒度對象,因此它又稱為輕量級模式,它是一種 對象結(jié)構(gòu)型模式。
線程池
心里沒底,還是先來個線程池壓壓驚吧。
//pthreadpool.h #pragma once #include //據(jù)說list不安全,不安全就不安全吧,更不安全的都忍了 #include "Cond.h" //封裝過的條件變量類,繼承自封裝的mutex鎖類,所以具有鎖和條件變量的雙重屬性 using namespace std; class Task //任務(wù)接口,每個任務(wù)必須實現(xiàn)的接口,以供工作線程調(diào)度任務(wù)的執(zhí)行 { public: Task() {} virtual ~Task() {} virtual int run() = 0; //留給子類實現(xiàn) }; typedef list
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
32
33
34
35
36
37
38
39
40
41
42
43
//pthreadpool.cpp #include "Pthread_Pool.h" //開放接口1 Pthread_Pool::Pthread_Pool(unsigned int max, unsigned int min, unsigned int wait) { //配置基本參數(shù) count = 0; //當(dāng)前線程池為空 waitcount = 0; //沒有等待線程 mincount = min; //核心線程數(shù)(出廠配置) maxcount = max; //最大線程數(shù)(能承受的最高配置) waitsec = wait; //線程保活時長(過了時長還沒接到任務(wù),那就裁掉) Stop = false; //允許運作 //上鎖,創(chuàng)建一定數(shù)量的線程作為初始線程池 cond.lock(); for (unsigned i = 0; i < mincount; i++) { createThread(); //跳轉(zhuǎn)到這個函數(shù)的實現(xiàn)->->->->-> } cond.unlock(); } Pthread_Pool::~Pthread_Pool() { destroyThread(); //銷毀線程池 } void Pthread_Pool::createThread() { pthread_t tid; int ret = pthread_create(&tid, NULL, taskThread, (void*)this); //以執(zhí)行taskThread()為目的創(chuàng)建線程,跳轉(zhuǎn)到taskThread()函數(shù)的實現(xiàn) ->->->->-> if (ret < 0) perror("pthread create error"); else count++; } // 工作線程 void* Pthread_Pool::taskThread(void* arg) { pthread_detach(pthread_self()); //設(shè)置線程自分離屬性 Pthread_Pool* pool = (Pthread_Pool*)arg; while (1) { pool->cond.lock(); //如果沒有工作線程在等待 if (pool->taskList.empty()) { if (pool->Stop) //當(dāng)收到線程池停止運行的消息時 { pool->count--; //線程數(shù)減一 pool->cond.unlock(); pthread_exit(NULL); //本線程強制退出 } pool->waitcount++; //等待任務(wù)的線程數(shù)加一 bool bSignal = pool->cond.timewait(pool->waitsec); //新任務(wù)等待被喚醒 pool->waitcount--; //沒等到,沒事干,喝西北風(fēng)了 // 刪除無用線程 if (!bSignal && pool->count > pool->mincount) //如果沒事干 && 有多余線程 { pool->count--; //先裁員一個,不要一次做絕了,反正是在while循環(huán)里面,沒事干裁員機會多得是 pool->cond.unlock(); pthread_exit(NULL); } } pool->cond.unlock(); //記得要釋放鎖 //如果有工作線程在等待 if (!pool->taskList.empty()) { pool->taskCond.lock(); //上任務(wù)鎖 Task* t = pool->taskList.front(); //獲取任務(wù)隊列中最前端的任務(wù)并執(zhí)行 pool->taskList.pop_front(); //移除被領(lǐng)取的任務(wù) pool->taskCond.unlock();//記得解鎖 t->run(); //任務(wù)開始 delete t; //弄完就刪了 } } pthread_exit(NULL); } //開放接口2,向任務(wù)隊列中添加任務(wù) void Pthread_Pool::addTask(Task* task) { if (Stop) //線程池是否停止工作 return; //向任務(wù)隊列中添加新任務(wù) taskCond.lock(); //上任務(wù)鎖 taskList.push_back(task); //添加任務(wù) taskCond.unlock(); //記得解鎖 cond.lock(); //上線程鎖 if (waitcount) //如果有空閑線程 { cond.signal(); //喚醒一個線程 } else if (count < maxcount) //如果沒有空閑線程,一般來說,走到這里面來,那這個線程池的設(shè)計是有點失敗了 { createThread(); //那就創(chuàng)建一個 cond.signal(); //然后喚醒 } cond.unlock(); } void Pthread_Pool::destroyThread() { printf("destroy?\n"); #if 0 //強行清理 list_task::iterator it = taskList.begin(); for (; it!= taskList.end(); it++) { Task* t = *it; delete t; t = NULL; } taskList.clear(); #endif // 等待所有線程執(zhí)行完畢 Stop = true; while (count > 0) { cond.lock(); cond.broadcast(); //廣播 cond.unlock(); sleep(1); } }
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
調(diào)用的地方是這樣的:
class DoTask : public Task { public: DoTask(BtoC& send, PacketCommand1& packet); int run(); private: DB_command* task_db; BtoC* m_send; PacketCommand1 m_packet; PacketCommand3* f_packet; }; class BackServer { public: BackServer(char* IPnum); ~BackServer() {} int run(); private: PacketCommand1 m_packet; BtoC m_send; Pthread_Pool* m_pool; };
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
int BackServer::run() { int n = 0; while (1) { n = m_send.Read_date(m_packet.getData()); m_packet.setSize(n); DoTask* t = new DoTask(m_send, m_packet); m_pool->addTask(t); } return 0; }
1
2
3
4
5
6
7
8
9
10
11
12
在這個線程池中呢,可以看到負責(zé)創(chuàng)建線程和管理線程的函數(shù)(享元工廠)、每條線程的共用屬性(外部屬性)、傳遞給每個線程的不同任務(wù)(內(nèi)部屬性),還有負責(zé)緩沖的任務(wù)隊列。
這些部分(享元工廠、元素外部屬性、元素內(nèi)部屬性),就是享元模式的主要構(gòu)成。
不過,在線程池調(diào)用的過程中,確是存在了一個問題:
DoTask* t = new DoTask(m_send, m_packet)
;這個可不見得回收了,要是等著系統(tǒng)的垃圾回收機制也是可以的,但是在高并發(fā)的情況下,這些尸位素餐的
DoTask* t
無疑成為了等待資源的任務(wù)們的“公敵”。
那么,今天我就來弄一個對象池,解決這個問題。
對象池類圖
對象公有屬性: (SignInfo)
DB_command* task_db; PacketCommand3* f_packet;
1
2
對象公有方法:
virtual int run(); virtual void setidentify(string identify); virtual string getidentify();
1
2
3
對象私有屬性:(SignInfoPool)
BtoC* m_send; PacketCommand1 m_packet; string identify; //身份標(biāo)識 int state; //是否處于空閑態(tài)
1
2
3
4
對象私有方法:
int run(); void setidentify(string identify); string getidentify();
1
2
3
享元工廠屬性:
map
1
享元工廠方法:
SignInfo* getSignInfo(string identify);
1
這樣可好?
畫個圖看看:
接下來代碼實現(xiàn)看看。
對象池代碼實現(xiàn)
#include
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
初次上手“享元模式”,多有紕漏,再寫之時會整合成一個類,像線程池那樣。
任務(wù)調(diào)度
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。