2013-12-16 95 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); 

,并没有更多的泄漏,线程停止如我所料。 感谢所有试图帮助的人。