2013-12-16 40 views
4

我有一個相當簡單的線程池,並且我有一個關於線程終結的問題。pthread退出線程池中的線程

這是我的工人片段:

static void* threadpool_worker(void* pool_instance) 
{ 
    int rc; 
    struct threadpool* pool = (struct threadpool*)pool_instance; 
    struct threadpool_task *task; 

    for(;;) 
    { 
     pthread_mutex_lock(&(pool->task_queue_mutex)); 

     while(pool->headp->tqh_first == NULL) 
     { 
      rc = pthread_cond_wait(&(pool->task_queue_cond), &(pool->task_queue_mutex)); 
     } 

     task = pool->headp->tqh_first; 
     TAILQ_REMOVE(pool->headp, pool->headp->tqh_first, entries); 

     pthread_mutex_unlock(&(pool->task_queue_mutex)); 
     task->routine_cb(task->data); 
    } 

} 

所以作業在此行中執行任務 - > routine_cb(任務 - >數據);

,並以最後確定工人線程我打電話threadpool_enqueue_task

下列方式

for(i=0 ; i < pool->num_of_workers ; ++i) 
{ 
    threadpool_enqueue_task(pool, pthread_exit, NULL); 
} 

期待的是將了pthread_exit這裏被稱爲任務 - > routine_cb(任務 - >數據) 但它不會以這種方式工作,我沒有看到任何明確的錯誤,只是內存泄漏的valgrind

,但是當我改變工人的代碼那樣:

if(task->routine_cb == pthread_exit) 
    { 
     pthread_exit(0); 
    } 
    task->routine_cb(task->data); 

一切都很好。 所以我的問題是有沒有一個選項來阻止工作者只是以某種方式執行pthread_exit,而無需更改工人代碼。

編輯: 線程池的任務聲明如下:

struct threadpool_task 
{ 
    void (*routine_cb)(void*); 
    void *data; 
    TAILQ_ENTRY(threadpool_task) entries;   /* List. */ 
} 

按我understanig應該沒有問題routine_cb得到了pthread_exit的地址,從而宣告:

extern void pthread_exit (void *__retval) __attribute__ ((__noreturn__)); 
+0

對您有幫助嗎? http://stackoverflow.com/questions/2084830/kill-thread-in-pthread-library –

+0

他們建議實際上我試圖避免的東西,ID不想從該帖子中提到的原因使用pthread_cancel: pthread_cancel(thr) 但是,這不是一個推薦的編程習慣!最好使用線程間通信機制(如信號量或消息)來與線程通信以停止執行。 – Dabo

+0

你使用什麼OS /編譯器? –

回答

0

我找到了泄漏的原因。當然,這是我的錯。我重寫以下列方式工作調用:

void (*routine)(void*) = task->routine_cb; 
    void* data = task->data; 
    free(task); 
    routine(data); 

代替:

task->routine_cb(task->data); 
    free(task); 

,並沒有更多的泄漏,線程停止如我所料。 感謝所有試圖幫助的人。