【发布时间】:2013-12-16 09:44:09
【问题描述】:
我有一个相当简单的线程池,我有一个关于线程终结的问题。
这是我的工人 sn-p:
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__));
【问题讨论】:
-
他们实际上提出了一些我试图避免的事情,我不想使用 pthread_cancel 出于该帖子中提到的原因:pthread_cancel(thr) 但是,这不是推荐的编程实践!最好使用信号量或消息等线程间通信机制与应该停止执行的线程进行通信。
-
你使用什么操作系统/编译器?
-
routine_cb是如何声明的? -
未知数太多。你能在一个独立的小例子中重现这种行为吗?
标签: c multithreading pthreads