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

标签 c linux multithreading free

我需要创建一个线程池,它可以工作,但是在函数 pthread_create 调用的函数 do_work 中,我在调用 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);   

}
 }

最佳答案

该模式看起来像一个相当标准的线程池:

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 的实现在哪里泄漏了内存。最有可能的候选者是每个 work_t 中 OP 的 arg 成员(如果它是动态分配的)。

我上面的实现将整个 work_t 传递给 routine 函数,我将其重命名为 process。它还负责释放工作结构。工作结构的最小定义是

typedef struct work_t {
    struct work_t  *next;
    void          (*process)(struct work_t *);
    /* Optional other fields */
} work_t;

内存泄漏的其他可能原因是 qsize 成员未在各处正确更新。因为它没有任何用处,真的,我干脆省略它。

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

关于c - 调用 pthread_exit() 时发生内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54106194/

相关文章:

c - 如何对结构的二维动态数组进行排序

Linux 应用程序 - 最小化依赖性

linux - 未定义的图书馆引用,所以我怎么能找到正确的路径?

Java 多线程挑战

c - 如何动态对齐结构的变量?

c - 如何将 double 组传递给 C 中的函数?

c - 如何从C中的函数返回2个暗淡字符数组

linux - 如何通过ssh获取远程命令的退出代码

取消或杀死 pthread

Java:基于时间的线程锁定