c++多線程編程html
一直對多線程編程這一塊很陌生,決定花一點時間整理一下。ios
os:ubuntu 10.04 c++c++
1.最基礎,進程同時建立5個線程,各自調用同一個函數sql
1 #include <iostream> 2 #include <pthread.h> //多線程相關操做頭文件,可移植衆多平臺 3 4 using namespace std; 5 6 #define NUM_THREADS 5 //線程數 7 8 void* say_hello( void* args ) 9 { 10 cout << "hello..." << endl; 11 } //函數返回的是函數指針,便於後面做爲參數 12 13 int main() 14 { 15 pthread_t tids[NUM_THREADS]; //線程id 16 for( int i = 0; i < NUM_THREADS; ++i ) 17 { 18 int ret = pthread_create( &tids[i], NULL, say_hello, NULL ); //參數:建立的線程id,線程參數,線程運行函數的起始地址,運行函數的參數 19 if( ret != 0 ) //建立線程成功返回0 20 { 21 cout << "pthread_create error:error_code=" << ret << endl; 22 } 23 } 24 pthread_exit( NULL ); //等待各個線程退出後,進程才結束,不然進程強制結束,線程處於未終止的狀態 25 }
輸入命令:g++ -o muti_thread_test_1 muti_thread_test_1.cpp -lpthread數據庫
注意:編程
1)此爲c++程序,故用g++來編譯生成可執行文件,而且要調用處理多線程操做相關的靜態連接庫文件pthread。ubuntu
2)-lpthread 編譯選項到位置可任意,如g++ -lpthread -o muti_thread_test_1 muti_thread_test_1.cppcentos
3)注意gcc和g++的區別,轉到此文:點擊打開連接數組
測試結果:緩存
1 wq@wq-desktop:~/coding/muti_thread$ ./muti_thread_test_1 2 hello...hello... 3 hello... 4 hello... 5 6 hello...
1 wq@wq-desktop:~/coding/muti_thread$ ./muti_thread_test_1 2 hello...hello...hello... 3 4 hello... 5 hello...
可知,兩次運行的結果會有差異,這不是多線程的特色吧?這顯然沒有同步?還有待進一步探索...
多線程的運行是混亂的,混亂就是正常?
2.線程調用到函數在一個類中,那必須將該函數聲明爲靜態函數函數
由於靜態成員函數屬於靜態全局區,線程能夠共享這個區域,故能夠各自調用。
1 #include <iostream> 2 #include <pthread.h> 3 4 using namespace std; 5 6 #define NUM_THREADS 5 7 8 class Hello 9 { 10 public: 11 static void* say_hello( void* args ) 12 { 13 cout << "hello..." << endl; 14 } 15 }; 16 17 int main() 18 { 19 pthread_t tids[NUM_THREADS]; 20 for( int i = 0; i < NUM_THREADS; ++i ) 21 { 22 int ret = pthread_create( &tids[i], NULL, Hello::say_hello, NULL ); 23 if( ret != 0 ) 24 { 25 cout << "pthread_create error:error_code" << ret << endl; 26 } 27 } 28 pthread_exit( NULL ); 29 }
測試結果:
1 wq@wq-desktop:~/coding/muti_thread$ ./muti_thread_test_2 2 hello... 3 hello... 4 hello... 5 hello... 6 hello...
1 wq@wq-desktop:~/coding/muti_thread$ ./muti_thread_test_2 2 hello...hello...hello... 3 4 5 hello... 6 hello...
3.如何在線程調用函數時傳入參數呢?
先看下面修改的代碼,傳入線程編號做爲參數:
1 #include <iostream> 2 #include <pthread.h> //多線程相關操做頭文件,可移植衆多平臺 3 4 using namespace std; 5 6 #define NUM_THREADS 5 //線程數 7 8 void* say_hello( void* args ) 9 { 10 int i = *( (int*)args ); //對傳入的參數進行強制類型轉換,由無類型指針轉變爲整形指針,再用*讀取其指向到內容 11 cout << "hello in " << i << endl; 12 } //函數返回的是函數指針,便於後面做爲參數 13 14 int main() 15 { 16 pthread_t tids[NUM_THREADS]; //線程id 17 cout << "hello in main.." << endl; 18 for( int i = 0; i < NUM_THREADS; ++i ) 19 { 20 int ret = pthread_create( &tids[i], NULL, say_hello, (void*)&i ); //傳入到參數必須強轉爲void*類型,即無類型指針,&i表示取i的地址,即指向i的指針 21 cout << "Current pthread id = " << tids[i] << endl; //用tids數組打印建立的進程id信息 22 if( ret != 0 ) //建立線程成功返回0 23 { 24 cout << "pthread_create error:error_code=" << ret << endl; 25 } 26 } 27 pthread_exit( NULL ); //等待各個線程退出後,進程才結束,不然進程強制結束,線程處於未終止的狀態 28 }
測試結果:
顯然不是想要的結果,調用順序很亂,這是爲何呢?
這是由於多線程到緣故,主進程還沒開始對i賦值,線程已經開始跑了...?
修改代碼以下:
1 #include <iostream> 2 #include <pthread.h> //多線程相關操做頭文件,可移植衆多平臺 3 4 using namespace std; 5 6 #define NUM_THREADS 5 //線程數 7 8 void* say_hello( void* args ) 9 { 10 cout << "hello in thread " << *( (int *)args ) << endl; 11 } //函數返回的是函數指針,便於後面做爲參數 12 13 int main() 14 { 15 pthread_t tids[NUM_THREADS]; //線程id 16 int indexes[NUM_THREADS]; //用來保存i的值避免被修改 17 18 for( int i = 0; i < NUM_THREADS; ++i ) 19 { 20 indexes[i] = i; 21 int ret = pthread_create( &tids[i], NULL, say_hello, (void*)&(indexes[i]) ); 22 if( ret != 0 ) //建立線程成功返回0 23 { 24 cout << "pthread_create error:error_code=" << ret << endl; 25 } 26 } 27 for( int i = 0; i < NUM_THREADS; ++i ) 28 pthread_join( tids[i], NULL ); //pthread_join用來等待一個線程的結束,是一個線程阻塞的函數 29 }
測試結果:
1 wq@wq-desktop:~/coding/muti_thread$ ./muti_thread_test_3 2 hello in thread hello in thread hello in thread hello in thread hello in thread 30124
這是正常的嗎?感受仍是有問題...待續
代碼中若是沒有pthread_join主線程會很快結束從而使整個進程結束,從而使建立的線程沒有機會開始執行就結束了。加入pthread_join後,主線程會一直等待直到等待的線程結束本身才結束,使建立的線程有機會執行。
4.線程建立時屬性參數的設置pthread_attr_t及join功能的使用
線程的屬性由結構體pthread_attr_t進行管理。
typedef struct
{
int detachstate; 線程的分離狀態
int schedpolicy; 線程調度策略
struct sched_param schedparam; 線程的調度參數
int inheritsched; 線程的繼承性
int scope; 線程的做用域
size_t guardsize; 線程棧末尾的警惕緩衝區大小
int stackaddr_set; void * stackaddr; 線程棧的位置
size_t stacksize; 線程棧的大小
}pthread_attr_t;
1 #include <iostream> 2 #include <pthread.h> 3 4 using namespace std; 5 6 #define NUM_THREADS 5 7 8 void* say_hello( void* args ) 9 { 10 cout << "hello in thread " << *(( int * )args) << endl; 11 int status = 10 + *(( int * )args); //線程退出時添加退出的信息,status供主程序提取該線程的結束信息 12 pthread_exit( ( void* )status ); 13 } 14 15 int main() 16 { 17 pthread_t tids[NUM_THREADS]; 18 int indexes[NUM_THREADS]; 19 20 pthread_attr_t attr; //線程屬性結構體,建立線程時加入的參數 21 pthread_attr_init( &attr ); //初始化 22 pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_JOINABLE ); //是設置你想要指定線程屬性參數,這個參數代表這個線程是能夠join鏈接的,join功能表示主程序能夠等線程結束後再去作某事,實現了主程序和線程同步功能 23 for( int i = 0; i < NUM_THREADS; ++i ) 24 { 25 indexes[i] = i; 26 int ret = pthread_create( &tids[i], &attr, say_hello, ( void* )&( indexes[i] ) ); 27 if( ret != 0 ) 28 { 29 cout << "pthread_create error:error_code=" << ret << endl; 30 } 31 } 32 pthread_attr_destroy( &attr ); //釋放內存 33 void *status; 34 for( int i = 0; i < NUM_THREADS; ++i ) 35 { 36 int ret = pthread_join( tids[i], &status ); //主程序join每一個線程後取得每一個線程的退出信息status 37 if( ret != 0 ) 38 { 39 cout << "pthread_join error:error_code=" << ret << endl; 40 } 41 else 42 { 43 cout << "pthread_join get status:" << (long)status << endl; 44 } 45 } 46 }
測試結果:
1 wq@wq-desktop:~/coding/muti_thread$ ./muti_thread_test_4 2 hello in thread hello in thread hello in thread hello in thread 0hello in thread 321 3 4 5 6 4 7 pthread_join get status:10 8 pthread_join get status:11 9 pthread_join get status:12 10 pthread_join get status:13 11 pthread_join get status:14
5.互斥鎖的實現
互斥鎖是實現線程同步的一種機制,只要在臨界區先後對資源加鎖就能阻塞其餘進程的訪問。
1 #include <iostream> 2 #include <pthread.h> 3 4 using namespace std; 5 6 #define NUM_THREADS 5 7 8 int sum = 0; //定義全局變量,讓全部線程同時寫,這樣就須要鎖機制 9 pthread_mutex_t sum_mutex; //互斥鎖 10 11 void* say_hello( void* args ) 12 { 13 cout << "hello in thread " << *(( int * )args) << endl; 14 pthread_mutex_lock( &sum_mutex ); //先加鎖,再修改sum的值,鎖被佔用就阻塞,直到拿到鎖再修改sum; 15 cout << "before sum is " << sum << " in thread " << *( ( int* )args ) << endl; 16 sum += *( ( int* )args ); 17 cout << "after sum is " << sum << " in thread " << *( ( int* )args ) << endl; 18 pthread_mutex_unlock( &sum_mutex ); //釋放鎖,供其餘線程使用 19 pthread_exit( 0 ); 20 } 21 22 int main() 23 { 24 pthread_t tids[NUM_THREADS]; 25 int indexes[NUM_THREADS]; 26 27 pthread_attr_t attr; //線程屬性結構體,建立線程時加入的參數 28 pthread_attr_init( &attr ); //初始化 29 pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_JOINABLE ); //是設置你想要指定線程屬性參數,這個參數代表這個線程是能夠join鏈接的,join功能表示主程序能夠等線程結束後再去作某事,實現了主程序和線程同步功能 30 pthread_mutex_init( &sum_mutex, NULL ); //對鎖進行初始化 31 32 for( int i = 0; i < NUM_THREADS; ++i ) 33 { 34 indexes[i] = i; 35 int ret = pthread_create( &tids[i], &attr, say_hello, ( void* )&( indexes[i] ) ); //5個進程同時去修改sum 36 if( ret != 0 ) 37 { 38 cout << "pthread_create error:error_code=" << ret << endl; 39 } 40 } 41 pthread_attr_destroy( &attr ); //釋放內存 42 void *status; 43 for( int i = 0; i < NUM_THREADS; ++i ) 44 { 45 int ret = pthread_join( tids[i], &status ); //主程序join每一個線程後取得每一個線程的退出信息status 46 if( ret != 0 ) 47 { 48 cout << "pthread_join error:error_code=" << ret << endl; 49 } 50 } 51 cout << "finally sum is " << sum << endl; 52 pthread_mutex_destroy( &sum_mutex ); //註銷鎖 53 }
測試結果:
可知,sum的訪問和修改順序是正常的,這就達到了多線程的目的了,可是線程的運行順序是混亂的,混亂就是正常?
6.信號量的實現
信號量是線程同步的另外一種實現機制,信號量的操做有signal和wait,本例子採用條件信號變量pthread_cond_t tasks_cond;
信號量的實現也要給予鎖機制。
1 #include <iostream> 2 #include <pthread.h> 3 #include <stdio.h> 4 5 using namespace std; 6 7 #define BOUNDARY 5 8 9 int tasks = 10; 10 pthread_mutex_t tasks_mutex; //互斥鎖 11 pthread_cond_t tasks_cond; //條件信號變量,處理兩個線程間的條件關係,當task>5,hello2處理,反之hello1處理,直到task減爲0 12 13 void* say_hello2( void* args ) 14 { 15 pthread_t pid = pthread_self(); //獲取當前線程id 16 cout << "[" << pid << "] hello in thread " << *( ( int* )args ) << endl; 17 18 bool is_signaled = false; //sign 19 while(1) 20 { 21 pthread_mutex_lock( &tasks_mutex ); //加鎖 22 if( tasks > BOUNDARY ) 23 { 24 cout << "[" << pid << "] take task: " << tasks << " in thread " << *( (int*)args ) << endl; 25 --tasks; //modify 26 } 27 else if( !is_signaled ) 28 { 29 cout << "[" << pid << "] pthread_cond_signal in thread " << *( ( int* )args ) << endl; 30 pthread_cond_signal( &tasks_cond ); //signal:向hello1發送信號,代表已經>5 31 is_signaled = true; //代表信號已發送,退出此線程 32 } 33 pthread_mutex_unlock( &tasks_mutex ); //解鎖 34 if( tasks == 0 ) 35 break; 36 } 37 } 38 39 void* say_hello1( void* args ) 40 { 41 pthread_t pid = pthread_self(); //獲取當前線程id 42 cout << "[" << pid << "] hello in thread " << *( ( int* )args ) << endl; 43 44 while(1) 45 { 46 pthread_mutex_lock( &tasks_mutex ); //加鎖 47 if( tasks > BOUNDARY ) 48 { 49 cout << "[" << pid << "] pthread_cond_signal in thread " << *( ( int* )args ) << endl; 50 pthread_cond_wait( &tasks_cond, &tasks_mutex ); //wait:等待信號量生效,接收到信號,向hello2發出信號,跳出wait,執行後續 51 } 52 else 53 { 54 cout << "[" << pid << "] take task: " << tasks << " in thread " << *( (int*)args ) << endl; 55 --tasks; 56 } 57 pthread_mutex_unlock( &tasks_mutex ); //解鎖 58 if( tasks == 0 ) 59 break; 60 } 61 } 62 63 64 int main() 65 { 66 pthread_attr_t attr; //線程屬性結構體,建立線程時加入的參數 67 pthread_attr_init( &attr ); //初始化 68 pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_JOINABLE ); //是設置你想要指定線程屬性參數,這個參數代表這個線程是能夠join鏈接的,join功能表示主程序能夠等線程結束後再去作某事,實現了主程序和線程同步功能 69 pthread_cond_init( &tasks_cond, NULL ); //初始化條件信號量 70 pthread_mutex_init( &tasks_mutex, NULL ); //初始化互斥量 71 pthread_t tid1, tid2; //保存兩個線程id 72 int index1 = 1; 73 int ret = pthread_create( &tid1, &attr, say_hello1, ( void* )&index1 ); 74 if( ret != 0 ) 75 { 76 cout << "pthread_create error:error_code=" << ret << endl; 77 } 78 int index2 = 2; 79 ret = pthread_create( &tid2, &attr, say_hello2, ( void* )&index2 ); 80 if( ret != 0 ) 81 { 82 cout << "pthread_create error:error_code=" << ret << endl; 83 } 84 pthread_join( tid1, NULL ); //鏈接兩個線程 85 pthread_join( tid2, NULL ); 86 87 pthread_attr_destroy( &attr ); //釋放內存 88 pthread_mutex_destroy( &tasks_mutex ); //註銷鎖 89 pthread_cond_destroy( &tasks_cond ); //正常退出 90 }
測試結果:
先在線程2中執行say_hello2,再跳轉到線程1中執行say_hello1,直到tasks減到0爲止。
1 wq@wq-desktop:~/coding/muti_thread$ ./muti_thread_test_6 2 [3069823856] hello in thread 2 3 [3078216560] hello in thread 1[3069823856] take task: 10 in thread 2 4 5 [3069823856] take task: 9 in thread 2 6 [3069823856] take task: 8 in thread 2 7 [3069823856] take task: 7 in thread 2 8 [3069823856] take task: 6 in thread 2 9 [3069823856] pthread_cond_signal in thread 2 10 [3078216560] take task: 5 in thread 1 11 [3078216560] take task: 4 in thread 1 12 [3078216560] take task: 3 in thread 1 13 [3078216560] take task: 2 in thread 1 14 [3078216560] take task: 1 in thread 1
到此,對多線程編程有了一個初步的瞭解,固然還有其餘實現線程同步的機制,有待進一步探索。
在開發C++程序時,通常在吞吐量、併發、實時性上有較高的要求。設計C++程序時,總結起來能夠從以下幾點提升效率:
下面將我日常工做中遇到一些問題例舉一二,其設計思想無非以上三點。
生產者-消費者模型是人們很是熟悉的模型,好比在某個服務器程序中,當User數據被邏輯模塊修改後,就產生一個更新數據庫的任務(produce),投遞給IO模塊任務隊列,IO模塊從任務隊列中取出任務執行sql操做(consume)。
設計通用的任務隊列,示例代碼以下:
詳細實現可參見:
http://ffown.googlecode.com/svn/trunk/fflib/include/detail/task_queue_impl.h
1 void task_queue_t::produce(const task_t& task_) { 2 lock_guard_t lock(m_mutex); 3 if (m_tasklist->empty()){//! 條件知足喚醒等待線程 4 m_cond.signal(); 5 } 6 m_tasklist->push_back(task_); 7 } 8 int task_queue_t::comsume(task_t& task_){ 9 lock_guard_t lock(m_mutex); 10 while (m_tasklist->empty())//! 當沒有做業時,就等待直到條件知足被喚醒{ 11 if (false == m_flag){ 12 return -1; 13 } 14 m_cond.wait(); 15 } 16 task_ = m_tasklist->front(); 17 m_tasklist->pop_front(); 18 return 0; 19 }
好比網絡遊戲服務器程序中,網絡模塊收到消息包,投遞給邏輯層後當即返回,繼續接受下一個消息包。邏輯線程在一個沒有io操做的環境下運行,以保障實時性。示例:
1 void handle_xx_msg(long uid, const xx_msg_t& msg){ 2 logic_task_queue->post(boost::bind(&servie_t::proces, uid, msg)); 3 }
注意,此模式下爲單任務隊列,每一個任務隊列單線程。
上面的只是完成了io 和 cpu運算的並行,而cpu中邏輯操做是串行的。在某些場合,cpu邏輯運算部分也可實現並行,如遊戲中用戶A種菜和B種菜兩種操做是徹底能夠並行的,由於兩個操做沒有共享數據。最簡單的方式是A、B相關的操做被分配到不一樣的任務隊列中。示例以下:
1 void handle_xx_msg(long uid, const xx_msg_t& msg) { 2 logic_task_queue_array[uid % sizeof(logic_task_queue_array)]->post( 3 boost::bind(&servie_t::proces, uid, msg)); 4 }
注意,此模式下爲多任務隊列,每一個任務隊列單線程。
好比邏輯Service模塊須要數據庫模塊異步載入用戶數據,並作後續處理計算。而數據庫模塊擁有一個固定鏈接數的鏈接池,當執行SQL的任務到來時,選擇一個空閒的鏈接,執行SQL,並把SQL 經過回調函數傳遞給邏輯層。其步驟以下:
示例以下:
1 void db_t:load(long uid_, boost::function<void (user_data_t&) func_){ 2 //! sql execute, construct user_data_t user 3 func_(user) 4 } 5 void process_user_data_loaded(user_data_t&){ 6 //! todo something 7 } 8 db_task_queue->post(boost::bind(&db_t:load, uid, func));
注意,此模式下爲單任務隊列,每一個任務隊列多線程。
本文主要講C++多線程編程,日誌系統不是爲了提升程序效率,可是在程序調試、運行期排錯上,日誌是無可替代的工具,相信開發後臺程序的朋友都會使用日誌。常見的日誌使用方式有以下幾種:
兩者各有優缺點,流式是線程安全的,printf格式格式化字符串會更直接,但缺點是線程不安全,若是把app_string.c_str() 換成app_string (std::string),編譯被經過,可是運行期會crash(若是運氣好每次都crash,運氣很差偶爾會crash)。我我的鐘愛printf風格,能夠作以下改進:
1 template<typename ARG1> 2 void logtrace(const char* module, const char* fmt, ARG1 arg1){ 3 boost::format s(fmt); 4 f % arg1; 5 }
這樣,除了標準類型+std::string 傳入其餘類型將編譯不能經過。這裏只列舉了一個參數的例子,能夠重載該版本支持更多參數,若是你願意,能夠支持9個參數或更多。
更多顏色方案參見:
http://hi.baidu.com/jiemnij/blog/item/d95df8c28ac2815cb219a80e.html
儘管已經有不少工具能夠分析c++程序運行性能,可是其大部分仍是運行在程序debug階段。咱們須要一種手段在debug和release階段都能監控程序,一方面得知程序瓶頸之所在,一方面儘早發現哪些組件在運行期出現了異常。
一般都是使用gettimeofday 來計算某個函數開銷,能夠精確到微妙。能夠利用C++的肯定性析構,很是方便的實現獲取函數開銷的小工具,示例以下
1 struct profiler{ 2 profiler(const char* func_name){ 3 gettimeofday(&tv, NULL); 4 m_func_name=func_name; 5 } 6 ~profiler(){ 7 struct timeval tv2; 8 gettimeofday(&tv2, NULL); 9 long cost = (tv.tv_sec - tv.tv_sec) * 1000000 + (tv.tv_usec - tv.tv_usec); 10 //! post to some manager 11 } 12 struct timeval tv; 13 const char * m_func_name; 14 }; 15 #define PROFILER() profiler ____profiler_instance##__LINE__(__FUNCTION__)
Cost 應該被投遞到性能統計管理器中,該管理器定時講性能統計數據輸出到文件中。
不少編程語言已經內建了foreach,可是c++尚未。因此建議本身在須要遍歷容器的地方編寫foreach函數。習慣函數式編程的人應該會很是鍾情使用foreach,使用foreach的好處多多少少有些,如:
http://www.cnblogs.com/chsword/archive/2007/09/28/910011.html
但主要是編程哲學上層面的。
示例:
1 void user_mgr_t::foreach(boost::function<void (user_t&)> func_){ 2 for (iterator it = m_users.begin(); it != m_users.end() ++it){ 3 func_(it->second); 4 } 5 }
好比要實現dump 接口,不須要重寫關於迭代器的代碼
1 void user_mgr_t:dump(){ 2 struct lambda { 3 static void print(user_t& user){ 4 //! print(tostring(user); 5 } 6 }; 7 this->foreach(lambda::print); 8 }
實際上,上面的代碼變通的生成了匿名函數,若是是c++ 11 標準的編譯器,本能夠寫的更簡潔一些:
this->foreach([](user_t& user) {} );
可是我大部分時間編寫的程序都要運行在centos 上,你知道嗎它的gcc版本是gcc 4.1.2, 因此大部分時間我都是用變通的方式使用lambda函數。
常見的使用任務隊列實現異步的代碼以下:
1 void service_t:async_update_user(long uid){ 2 task_queue->post(boost::bind(&service_t:sync_update_user_impl, this, uid)); 3 } 4 void service_t:sync_update_user_impl(long uid){ 5 user_t& user = get_user(uid); 6 user.update() 7 }
這樣作的缺點是,一個接口要響應的寫兩遍函數,若是一個函數的參數變了,那麼另外一個參數也要跟着改動。而且代碼也不是很美觀。使用lambda可讓異步看起來更直觀,彷彿就是在接口函數中馬上完成同樣。示例代碼:
1 void service_t:async_update_user(long uid){ 2 struct lambda { 3 static void update_user_impl(service_t* servie, long uid){ 4 user_t& user = servie->get_user(uid); 5 user.update(); 6 } 7 }; 8 task_queue->post(boost::bind(&lambda:update_user_impl, this, uid)); 9 }
這樣當要改動該接口時,直接在該接口內修改代碼,很是直觀。
Map/reduce的語義是先將任務劃分爲多個任務,投遞到多個worker中併發執行,其產生的結果經reduce彙總後生成最終的結果。Shared_ptr的語義是什麼呢?當最後一個shared_ptr析構時,將會調用託管對象的析構函數。語義和map/reduce過程很是相近。咱們只需本身實現講請求劃分多個任務便可。示例過程以下:
1 struct reducer{ 2 void set_result(int index, long result) { 3 m_result[index] = result; 4 } 5 ~reducer(){ 6 long total = 0; 7 for (int i = 0; i < sizeof(m_result); ++i){ 8 total += m_result[i]; 9 } 10 //! post total to somewhere 11 } 12 long m_result[10]; 13 };
1 void worker_t:exe(int index_, shared_ptr<reducer> ret) { 2 ret->set_result(index, 100); 3 }
1 shared_ptr<reducer> ret(new reducer()); 2 for (int i = 0; i < 10; ++i) 3 { 4 task_queue[i]->post(boost::bind(&worker_t:exe, i, ret)); 5 }