2013-03-26 173 views
0

我正在用pthreads創建一個線程池,並且當我知道它是如何工作的時,我有幾個問題錯綜複雜。在``C``線程池中運行'POSIX`線程在``C``線程池中運行`函數指針`

我創建了一個應該是我的線程池表示的結構,它包含要運行的函數指針列表,我們將其稱爲work_list。線程池結構還包含互斥鎖的(?)和條件來同步訪問,一個線程數的int和一個擁有每個工作線程的線程ID的數組。work_list本身包含表示要完成的函數的結構,這些結構的每個實例結構體對於函數具有void *,對於參數具有void *,並且對結果賦予void *。當編碼這個想法fleshes出這樣的:

typedef struct threadpool 
{ 
    list work_list; 
    pthread_t* tidArray; 
    int num_threads; 
    pthread_mutex_t lock; 
    pthread_cond_t condition; 
} threadpool; 

和:

typedef struct fuFunction 
{ 
    void* functionCall; 
    void* functionArgs; 
    void* returnValue; 
    list_elem elem; 
} fuFunction; 

我現在有它初始化一個池中的線程。它接受一個int num_of_threads,並返回一個指向所有成員初始化的線程池實例的指針。我創建了身體看起來是這樣的:

threadpool * threadpool_init(int num_of_threads) 
{ 
    threadpool* retPool = (threadpool*) malloc(sizeof(threadpool)); 

    //Initialize retPool members 

    int x; 
    for(x = 0; x < num_of_threads; x++) 
    { 
      pthread_t tid; 

      if(pthread_create(&tid, NULL, thread_start, retPool) != 0) 
      { 
        printf("Error creating worker thread\nExting\n"); 
        exit(1); 
      } 

      retPool->tidArray[x] = tid; 
    } 

    return retPool; 
} 

功能,每個線程運行啓動時,工人功能,thread_star,看起來像這樣至今:

void *thread_start(void* args) 
{ 
    threadpool* argue = (threadpool*) args; 

    pthread_mutex_lock(&(argue->lock)); 
    while(\* threadpool not shut down*\) 
    { 
      if(!list_empty(&argue->work_list)) 
      { 
        fuFunction* tempFu = list_entry(list_pop_front(&argue->workQ), fuFunction, elem); 

        \\WHAT TO PUT HERE 
      } 

      pthread_cond_wait(&argue->condition, &argue->lock); 
    } 
    pthread_mutex_unlock(&(argue->lock)); 
} 

我的問題是,假設我現在擁有的這段代碼是正確的,我將如何讓工作線程在工作函數中執行tempFu中的函數?對不起,如果這很長或令人困惑,我覺得這在談話中更容易解釋。如果這是FUBAR,請讓我知道。

回答

0

struct element signiture「void * functionCall;」是錯的。 改爲使用函數指針。 如:

typedef struct fuFunction 
{ 
    void* (*functionCall)(void* arg); 
    void* functionArgs; 
    void* returnValue; 
    list_elem elem; 
} fuFunction; 

然後放在那裏:

tempfu->returnValue = (*tempfu->functionCall)(tempfu->functionArgs);