我有一个相当简单的线程池,我对线程最终确定有疑问。
这是我的工作片段:
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__));
答案 0 :(得分:0)
我找到了泄漏的原因。当然是我的错。我用以下方式重写了作业调用:
void (*routine)(void*) = task->routine_cb;
void* data = task->data;
free(task);
routine(data);
而不是:
task->routine_cb(task->data);
free(task);
并且没有更多的泄漏,并且线程像我预期的那样停止了。 感谢所有试图提供帮助的人。