调用pthread_exit()时发生内存泄漏

时间:2019-01-09 08:49:11

标签: c linux multithreading free

我需要创建一个线程池,它可以工作,但是在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);   

}
 }

1 个答案:

答案 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成员未在所有地方正确更新。因为真的没有用,所以我完全省略了。

代码越简单,就越容易避免错误。