C++ 在類裏面使用多線程技術
阿新 • • 發佈:2019-03-24
name 錯誤 thread 聲明 time lib main 不能 轉化
有很多時候,我們希望可以在C++類裏面對那些比較耗時的函數使用多線程技術,但是,C++類的成員函數的函數指針不能直接做為參數傳到pthread_create,主要因為是C++成員函數指針帶有類命名空間,同時成員函數末尾是會被C++編譯器加上可以接收對象地址的this指針參數。因此需要將成員函數做一定的轉化,將其轉化為不被編譯器加上this指針,而由我們自己來為該函數維護”this”指針即可。
#include <stdio.h> #include <stdlib.h> #include <iostream> #include <time.h> #include <unistd.h> #include <pthread.h> using namespace std; class Test { public: int sum; int cnt; Test(){sum=0;} public: int insert(); void * insert_pth(void*); void lanch(); }; int Test::insert() { sleep(2); sum+=1; } void * Test::insert_pth(void*) { insert(); } void Test::lanch() { pthread_t pth; pthread_create(&pth,NULL,insert_pth,NULL); } int main() { Test t; t.lanch(); return 0; }
只需將insert_pth變化為static函數,同時將insert邏輯代碼轉移到insert_pth即可:
#include <stdio.h> #include <stdlib.h> #include <iostream> #include <time.h> #include <unistd.h> #include <pthread.h> using namespace std; class Test { public: int sum; int cnt; Test(){sum=0;} public: int insert(); static void * insert_pth(void*); void lanch(); }; int Test::insert() { sleep(2); sum+=1; printf("%d insert.....\n",sum); } void * Test::insert_pth(void* __this) { Test * _this =(Test *)__this; sleep(2); _this->sum+=1; printf("%d insert.....\n",_this->sum); } void Test::lanch() { pthread_t pth; pthread_create(&pth,NULL,insert_pth,(void*)this); } int main() { Test t; t.sum=0; t.lanch(); sleep(5); return 0; }
註意:
在 XXX_pth()函數內容盡量不要調用類的其它成員函數,否則成員函數將無法獲取正確的this指針而操作錯誤內存,從而導致segmantation fault
。
總結:
- 將線程函數聲明為靜態函數;
- 創建線程時傳遞進去this指針;
- 在線程函數中使用傳進來的this指針調用類的成員,特別註意調用類的成員函數時要避免
segmantation fault
錯誤。
C++ 在類裏面使用多線程技術