C++程式設計思想 第2卷 第11章 併發 使用執行緒 使用執行器簡化工作
使用ZThread的執行器 Executor 可以減少編碼的工作量 執行器在客戶和任務的執行之間提供了一個間接層 客戶不再直接執行任務 而是由一箇中間的物件來執行該任務這裡要改個名字 要不然會重名 出現函式未定義
//: c11:ThreadedExecutor1.cpp // From "Thinking in C++, Volume 2", by Bruce Eckel & Chuck Allison. // (c) 1995-2004 MindView, Inc. All Rights Reserved. // See source code use permissions stated in the file 'License.txt', // distributed with the code package available at www.MindView.net. //{L} ZThread #include <iostream> #include "zthread/ThreadedExecutor.h" #include "LiftOff.h" using namespace ZThread; using namespace std; int main() { try { ThreadedExecutor executor; for(int i = 0; i < 5; i++) executor.execute(new LiftOff(10, i)); } catch(Synchronization_Exception& e) { cerr << e.what() << endl; } getchar(); } ///:~
輸出 ThreadQueue created User thread created. Reference thread created. 1 reference-thread added. pollPendingThreads() 1 user-thread added. Thread starting... User thread created. 0pollPendingThreads() :1 user-thread added. 9Thread starting... User thread created. 1 :90 :18: 8pollPendingThreads()
1 user-thread added. 10User thread created. ::77
10Thread starting... :6 1pollPendingThreads() 1 user-thread added. 2Thread starting... :36: 9: 5User thread created.
0:2pollPendingThreads() 1 user-thread added. 5 0::49Thread starting...
0::348
3:18 :4: 9
3:27: 7 1:03 4::83 :6 4:17:22 :6
2:25
42:4 1::106
4:5 2:1:03::51 4: 43
0: 0 Liftoff! 4:23 3:44: Liftoff! :2Thread joining...
4:1Thread exiting...
4:insertPendingThread() 0 Thread joining... Thread exiting... insertPendingThread() Liftoff! 3:231 pending-thread added.
3:20Thread joining... completed
3: 1 1 pending-thread added. Thread exiting... insertPendingThread() 3:021 pending-thread added.
1 completed4 completed :1Liftoff!
2Thread joining... Thread exiting... :insertPendingThread() 01 pending-thread added.
3 completedLiftoff!
Thread joining... Thread exiting... insertPendingThread() 1 pending-thread added. 2 completed
某些情況下可以用單個的Executor物件來建立和管理系統中的所有執行緒 必須把執行緒處理程式碼放在一個try塊中 因為如果出現錯誤的話Executor的execute()函式可能會丟擲Synchronization_Exception異常
ThreadedExecutor 在產生的程式碼中 由於建立了太多的執行緒 ThreadedExecutor將會導致過多的開銷 可以使用PoolExecutor物件來替換ThreadedExecutor物件 它使用一個有限的執行緒集以並行的方式提交任務
ZThread庫有一個 PoolExecutor檔案
//: C11:PoolExecutor1.cpp
// From "Thinking in C++, Volume 2", by Bruce Eckel & Chuck Allison.
// (c) 1995-2004 MindView, Inc. All Rights Reserved.
// See source code use permissions stated in the file 'License.txt',
// distributed with the code package available at www.MindView.net.
//{L} ZThread
#include <iostream>
#include "zthread/PoolExecutor.h"
#include "LiftOff.h"
using namespace ZThread;
using namespace std;
int main() {
try {
// Constructor argument is minimum number of threads:
PoolExecutor executor(5);
for(int i = 0; i < 5; i++)
executor.execute(new LiftOff(10, i));
} catch(Synchronization_Exception& e) {
cerr << e.what() << endl;
}
getchar();
} ///:~
輸出 ThreadQueue created User thread created. Reference thread created. 1 reference-thread added. pollPendingThreads() 1 user-thread added. Thread starting... User thread created. pollPendingThreads() 1 user-thread added. Thread starting... User thread created. pollPendingThreads() 1 user-thread added. Thread starting... User thread created. pollPendingThreads() 1 user-thread added. Thread starting... User thread created. pollPendingThreads() 1 user-thread added. Thread starting... 041::993
4::829
:19: :28: 931 :74 :7: 8 8 2:74 1::66 3 :70 :8 2:6 1:253 4::550: 1:42: :4
7 0:612 6 :3 4:40 :3: 5 0:34:25:4 :32
2:1 0:342 :0: 23:40 :1: 2Liftoff! 3: 3 2 2 completed 4The task has thrown an unhandled exception :1 3:Thread joining... 2 3:1Thread exiting...
3:10: 4:insertPendingThread() 0 1 1:1 pending-thread added. 0 Liftoff! 0:1Liftoff! 0: 0 3 completed 4 completed Liftoff!Liftoff!
The task has thrown an unhandled exception 1Thread joining... 0Thread exiting... completed completed insertPendingThread() 1 pending-thread added. The task has thrown an unhandled exception Thread joining...
The task has thrown an unhandled exception Thread exiting... Thread joining... insertPendingThread() Thread exiting... 1 pending-thread added. insertPendingThread() The task has thrown an unhandled exception 1 pending-thread added. Thread joining... Thread exiting... insertPendingThread() 1 pending-thread added.
使用PoolExecutor 可以預先將開銷很大的執行緒分配工作一次做完 在可能的時候重用這些執行緒 這樣做節省時間 因為不會因不斷地為了每個任務都建立一個執行緒而付出那些開銷每個任務按其被提交的順序執行 並且在下一個任務開始之前執行完成 一個ConcurrentExecutor物件序列化 順序執行 提交給它的任務
//: C11:ConcurrentExecutor.cpp
// From "Thinking in C++, Volume 2", by Bruce Eckel & Chuck Allison.
// (c) 1995-2004 MindView, Inc. All Rights Reserved.
// See source code use permissions stated in the file 'License.txt',
// distributed with the code package available at www.MindView.net.
//{L} ZThread
#include <iostream>
#include "zthread/ConcurrentExecutor.h"
#include "LiftOff.h"
using namespace ZThread;
using namespace std;
int main() {
try {
ConcurrentExecutor executor;
for(int i = 0; i < 5; i++)
executor.execute(new LiftOff(10, i));
} catch(Synchronization_Exception& e) {
cerr << e.what() << endl;
}
getchar();
} ///:~
輸出 ThreadQueue created User thread created. Reference thread created. 1 reference-thread added. pollPendingThreads() 1 user-thread added. Thread starting... 0:9 0:8 0:7 0:6 0:5 0:4 0:3 0:2 0:1 0:0 Liftoff! 0 completed 1:9 1:8 1:7 1:6 1:5 1:4 1:3 1:2 1:1 1:0 Liftoff! 1 completed 2:9 2:8 2:7 2:6 2:5 2:4 2:3 2:2 2:1 2:0 Liftoff! 2 completed 3:9 3:8 3:7 3:6 3:5 3:4 3:3 3:2 3:1 3:0 Liftoff! 3 completed 4:9 4:8 4:7 4:6 4:5 4:4 4:3 4:2 4:1 4:0 Liftoff! 4 completed The task has thrown an unhandled exception Thread joining... Thread exiting... insertPendingThread() 1 pending-thread added.
就像ConcurrentExecutor SynchronousExecutor用於需要同一時刻只執行一個任務的時候 序列代替了併發 不像ConcurrentExecutor SynchronousExecutor自己不建立或管理執行緒
對資源的訪問採用同步方式進行 SynchronousExecutor可以跳過對適當合理的某些原型事件進行協調的麻煩
//: C11:SynchronousExecutor.cpp
// From "Thinking in C++, Volume 2", by Bruce Eckel & Chuck Allison.
// (c) 1995-2004 MindView, Inc. All Rights Reserved.
// See source code use permissions stated in the file 'License.txt',
// distributed with the code package available at www.MindView.net.
//{L} ZThread
#include <iostream>
#include "zthread/SynchronousExecutor.h"
#include "LiftOff.h"
using namespace ZThread;
using namespace std;
int main() {
try {
SynchronousExecutor executor;
for(int i = 0; i < 5; i++)
executor.execute(new LiftOff(10, i));
} catch(Synchronization_Exception& e) {
cerr << e.what() << endl;
}
getchar();
} ///:~
輸出 ThreadQueue created Reference thread created. 1 reference-thread added. 0:9 0:8 0:7 0:6 0:5 0:4 0:3 0:2 0:1 0:0 Liftoff! 0 completed 1:9 1:8 1:7 1:6 1:5 1:4 1:3 1:2 1:1 1:0 Liftoff! 1 completed 2:9 2:8 2:7 2:6 2:5 2:4 2:3 2:2 2:1 2:0 Liftoff! 2 completed 3:9 3:8 3:7 3:6 3:5 3:4 3:3 3:2 3:1 3:0 Liftoff! 3 completed 4:9 4:8 4:7 4:6 4:5 4:4 4:3 4:2 4:1 4:0 Liftoff! 4 completed
當執行程式時 將會看到任務以被提交的順序執行 每個任務在下一個任務啟動前完成 但是看不到有新執行緒建立