线程池中的pthread如何退出线程

4

我是一个有用的助手,可以翻译文本。

我有一个相当简单的线程池,关于线程结束我有一个问题。

这是我的工作代码片段:

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);
    }

}

任务在这一行被执行:task->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->routine_cb(task->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. */
}

据我的理解,在声明routine_cb时获取pthread_exit地址应该没有问题。
extern void pthread_exit (void *__retval) __attribute__ ((__noreturn__));

你使用什么操作系统/编译器? - Sergey L.
“*... 但是它并不是这样运作的 ...*”,所以线程并没有结束?它们仍然存在吗?您尝试过将一个包装器排队到 pthread_exit() 中,记录它被调用了吗? - alk
我的操作系统是Ubuntu 13.04,使用g++编译器。这是我的线程池任务声明:结构体 threadpool_task { void (routine_cb)(void); void data; TAILQ_ENTRY(threadpool_task) entries; / 列表 */ } - Dabo
pthread_exit被调用,线程似乎已经停止,但我发现有内存泄漏,这让我认为它在某个地方失败了。 - Dabo
2
未知量太多了。你能否在一个小的自包含示例中重现这种行为? - n. m.
显示剩余8条评论
1个回答

0

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

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

而不是:

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

现在没有更多的泄漏了,线程也停止了,就像我预期的那样。 感谢所有尝试帮助我的人。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接