pthread从线程池中的线程退出

时间:2013-12-16 09:44:10

标签: c multithreading pthreads

我有一个相当简单的线程池,我对线程最终确定有疑问。

这是我的工作片段:

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(task-> data);

并且为了完成工作线程我正在调用threadpool_enqueue_task

以下列方式:

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

期望在这里调用pthread_exit task-&gt; routine_cb(task-&gt; data) 但它没有这种方式工作,我没有看到任何明确的错误,只是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. */
}

根据我的说法,在regular_cb中获取pthread_exit的地址应该没有问题,声明:

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

1 个答案:

答案 0 :(得分:0)

我找到了泄漏的原因。当然是我的错。我用以下方式重写了作业调用:

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

而不是:

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

并且没有更多的泄漏,并且线程像我预期的那样停止了。 感谢所有试图提供帮助的人。