因為研究測試資料莫名的大,在生成資料的過程中,常常會有需要長時間等待的狀況,
這時就會想到當初課堂說的平行化處理,所以想說用thread來榨乾CPU的效能呀~
很幸運的是,在C++ 11之後,已經把thread列入標準凾式庫內了,
雖然早期的Compiler沒有支援,不過如果用IDE有乖乖升級的話,
應該之後的版本都會把這東西補進去
所以可以把那精美的pthread先放在一旁(pthread你好難懂呀~)
小弟在這邊個環境是在ubuntu上面,gcc version 4.4.3,
(真的比較習慣用vim寫code,直接上server跑資料也比較方便)
在使用上,編譯需要加上相關參數:
g++ source.cpp
-std=c++0x -lpthread -Os -o ./target
- -std=c++0x:指定編譯的C++版本
- -lpthread:引入thread的lib,是說也看到有-pthread的,目前測過兩個都可以
在程式碼內,需要引入「thread」的函式:#include <thread>
這樣就可以呼叫thread相關函式來
奴役充分利用CPU的資源了
在使用上,根據不同情境,使用的狀況會有所不同:
- 在main呼叫一般function
這應該是最容易理解的,根據cplusplus.com的範例,他的程式碼長這個樣子:
// thread example
#include <iostream> // std::cout
#include <thread> // std::thread
void foo()
{
// do stuff...
}
void bar(int x)
{
// do stuff...
}
int main()
{
std::thread first (foo); // 開新thread:「first」執行「foo」函式
std::thread second (bar,0); // 開新thread:「second」執行「bar」函式,傳入參數0
std::cout << "main, foo and bar now execute concurrently...\n";
// synchronize threads:
first.join(); // 等「first」thread執行結束
second.join(); // 等「second」thread執行結束
std::cout << "foo and bar completed.\n";
return 0;
}
因為C++ 11 thread已經將這個功能物件化,所以使用上就和使用一般物件一樣,
先生成一個物件,然後將要分工執行的function和參數傳進去,這時候main function就只要等待執行結束在收割結果就好啦!
- 在class內呼叫同個class內的member function
不過有時候,我們會需要在class裡面,針對特定的工作進行加速,像是某些需要大量重複計算又互不干擾的函式,這時候就會對單一個member function做thread加速,那這時得使用會變成:
#include <iostream>
#include <thread>
using namespace std;
ClassA::ClassA(){
// do stuff...
}
void ClassA::memberFunA(int a){
// do stuff...
}
void ClassA::memberFunB(){
std::thread first (&ClassA::memberFunA, this, 0);
first.join();
// do stuff...
}
以上面為例,memberFunB需要呼叫同一個class的memberFunA,因此需要引入member function的完整reference,並且第一個參數要代入是自己這個class,讓thread可以正確找到要引入的資料為何。
- 在main呼叫特定物件的member function
另一個情況是:在main function中需要將某些物件放到thread裡面做平行化運算:
#include <iostream>
#include <thread>
using namespace std;
int main( int argc, char** argv )
{
ClassA object1;
std::thread first (&ClassA::memberFunA, &object1, 0);
first.join();
}
在這邊的想法和2.類似:引入的function需要指定class和member function的reference,加上由於是用物件形式呼叫member function,因此需要在指定該物件的reference,才可以存取該物件內的member function
不過要注意的是,在引入物件進去thread平行化執行時,是將整個函式和變數複製一份到thread使用,因此如果有需要保留修改變數的狀況的話(EX: 引入一個陣列,裡面存修改後的狀況,讓多個thread個別修改一段),則需要加上「std::ref()」來處理。
以上大概就是C++裡面thread的基本使用,其實還有很多像是針對執行中thread的操作啦,thread間的溝通之類的東西,不過目前小弟還用不到那麼進階的功能,所以在這邊就先不提啦,之後有機會的話會再補上去。