類成員函式作為pthread create函式引數

2021-09-09 02:13:43 字數 2237 閱讀 3335

from:

近日需要將執行緒池封裝成c++類,類名為threadpool。在類的成員函式exec_task中呼叫pthread_create去啟動執行緒執行例程thread_rounter。編譯之後報錯如下:

spfs_threadpool.cpp: in member function 『int threadpool::exec_task(task*)』:

spfs_threadpool.cpp:174: error: argument of type 『void* (threadpool::)(void*)』 does not match 『void* (*)(void*)』

出現型別不匹配的問題。因為pthread_create需要的引數型別為void* (*)(void*),而thread_rounter作為類的成 員函式時其型別是void* (threadpool::)(void*)的成員函式指標。我們知道類的成員函式在經過編譯器處理之後,會變成帶有 this指標引數的全域性函式,所以型別注定是不會匹配的。但是如果將thread_rounter宣告為static型別,那麼編譯器會將static形 式的函式,轉換成不帶this指標的全域性函式,所以其型別可以與pthread_create需要的引數型別相匹配。但是類的靜態成員函式無法訪問類的非 靜態成員,不過這可以通過傳遞this指標解決這個問題。

綜上,我的這個問題可以這個樣子解決。

出問題之前的**:

void *thread_rounter(void *)//執行緒執行函式

//直接訪問類的成員

exec_task函式中呼叫:

pthread_create(&tid,null,thread_rounter,null);//啟動執行緒執行例程

修復這個問題的**:

static void *thread_rounter(void *tmp)/執行緒執行函式

threadpool *p=(threadpool *)tmp;

//通過p指標間接訪問類的非靜態成員

exec_task函式中呼叫:

pthread_create(&tid,null,thread_rounter,(void *)this);//啟動執行緒執行例程

在網上搜尋一下還有其他的解決方案,摘錄如下,為了以示尊重標明文章**,感謝原文作者。

方案二:

將執行緒啟動函式宣告為模板函式。

摘錄自:

template void (type::*_runthread)() >  

void* _thread_t(void* param)//

執行緒啟動函式,宣告為模板函式

class

myclass

; void

myclass::_runthread()

myclass::myclass()

//函式模版不單可以替換型別本身,還能替換型別的成員函式。 //

注意: 1、名稱只能是_runthread,不能在指定模版引數的時候修改; //

2、_runthread只能是public的,除非把_thread_t定義到myclass的內部。

採取這個方案放入我的專案中:

出問題之前的**:

void *thread_rounter(void *)//執行緒執行函式

//直接訪問類的成員

exec_task函式中呼叫:

pthread_create(&tid,null,thread_rounter,null);//啟動執行緒執行例程

修復這個問題的**:

新增public成員函式:

void run()

//該函式替換上述thread_rounter的執行**

thread_rounter修改為全域性模板函式:

template 

void * thread_rounter(void * param)

type *p=(type*)param;

p->run();

return null;

exec_task函式中呼叫:

pthread_create(&tid,null,thread_rounter,(void *)this);

總結:解決這個問題的關鍵在於想方設法使啟動函式指標滿足void*(*)(void *)型別。

將啟動函式改寫成static成員函式適用於可以修改類的源**的情況。

而將啟動函式寫成模板函式還可以適用於沒有類的源**的情況,自己寫乙個類,公共繼承自原類,新增啟動函式為模板函式即可。

類成員函式作為pthread create函式引數

近日需要將執行緒池封裝成c 類,類名為threadpool。在類的成員函式exec task中呼叫pthread create去啟動執行緒執行例程thread rounter。編譯之後報錯如下 spfs threadpool.cpp in member function int threadpool...

類成員函式作為執行緒函式

include windows.h include class exampletask void exampletask taskmain lpvoid param void exampletask starttask int main int argc,char argv 出現編譯錯誤 error...

類成員函式作為執行緒函式

黙 座 類成員函式作為執行緒函式 2011 01 10 14 54 43 分類 windows 字型大小 訂閱 類成員函式不能作為執行緒函式 一般來說,c 的類成員函式不能作為執行緒函式。這是因為在類中定義的成員函式,編譯器會給其加 上this指標。請看下列程式 include windows.h ...