我需要创建一个线程池,它可以工作,但是在do_work函数中,函数pthread_create调用仅在调用pthread_exit()时才出现空闲(内存泄漏)的问题
*在函数创建线程池中,我只是初始化结构并调用 功能确实有效*
void* do_work(void* p)
{
threadpool* pool = (threadpool*)p;
work_t* work;
while(1)
{
pthread_mutex_lock(&pool->qlock);
if(pool->shutdown == 1)
{
pthread_mutex_unlock(&pool->qlock);
//pthread_exit(EXIT_SUCCESS);// here is the free problem when deleting it all good
return NULL;
}
while(!pool->qsize)
{
if(pthread_cond_wait(&pool->q_not_empty,&pool->qlock))
perror("pthread_cond_wait\n");
if(pool->shutdown)
break;
}
//Check if the system is shutting down
if(pool->shutdown == 1)
{
pthread_mutex_unlock(&pool->qlock);
//pthread_exit(EXIT_SUCCESS);y
return NULL;
}
work = pool->qhead; //set the cur variable.
pool->qsize--; //decriment the size.
if(pool->qsize == 0) {
pool->qhead = NULL;
pool->qtail = NULL;
}
else {
pool->qhead = work->next;
}
if(pool->qsize == 0 && ! pool->shutdown) {
//the q is empty again, now signal that its empty.
pthread_cond_signal(&(pool->q_empty));
}
pthread_mutex_unlock(&(pool->qlock));
(work->routine) (work->arg); //actually do work.
free(work);
}
}
答案 0 :(得分:0)
该模式看起来像一个相当标准的线程池:
typedef struct {
pthread_mutex_t qlock;
pthread_cond_t q_not_empty;
volatile work_t *qhead;
volatile work_t *qtail;
size_t qsize; /* Not needed */
volatile int shutdown;
} threadpool;
正确缩进OP的代码将使其更具可读性。
但是,实现看起来很奇怪。我希望
void *do_work(void *poolptr)
{
threadpool *const pool = poolptr;
work_t *work;
pthread_mutex_lock(&(pool->qlock));
while (!(pool->shutdown)) {
if (!(pool->qhead)) {
/* Queue empty */
pthread_cond_wait(&(pool->q_not_empty), &(pool->qlock));
continue;
}
work = pool->qhead;
pool->qhead = work->next;
if (!pool->qhead)
pool->qtail = NULL;
work->next = NULL;
pthread_unlock(&(pool->qlock));
work->process(work);
pthread_lock(&(pool->qlock));
}
pthread_mutex_unlock(&(pool->qlock));
return (void *)0;
}
以及将新工作项追加到要添加的队列的代码
void append(threadpool *pool, work_t *work)
{
work->next = NULL;
pthread_mutex_lock(&(pool->qlock));
if (pool->qtail) {
pool->qtail->next = work;
pool->qtail = work;
} else {
pool->qhead = work;
pool->qtail = work;
}
pthread_cond_signal(&(pool->q_not_empty));
pthread_mutex_unlock(&(pool->qlock));
}
很难说OP的实现在哪里泄漏内存。如果它是动态分配的,则最可能的候选者是每个arg
中OP的work_t
成员。
我上面的实现将整个work_t
传递给routine
函数,我将其重命名为process
。它也负责释放工作结构。工作结构的最小定义是
typedef struct work_t {
struct work_t *next;
void (*process)(struct work_t *);
/* Optional other fields */
} work_t;
导致内存泄漏的其他可能原因是qsize
成员未在所有地方正确更新。因为真的没有用,所以我完全省略了。
代码越简单,就越容易避免错误。