即使在pthread_detach之后也会出现泄漏

时间:2016-08-28 20:21:17

标签: c pthreads valgrind exit resource-leak

如果我使用pthread_detach从一个端口线程终止整个程序,我正在尝试使用自清理线程代码来释放pthread_t资源,但是我仍然从valgrind获得可能丢失字节的内存泄漏报告。这是我的示例代码段:

pthread_t main_thread;
pthread_t second_thread;

void* thread_func() {
    pthread_detach(pthread_self());
    exit(0);
}

int main() {
    main_thread = pthread_self(); // record main thread in case needed later
    pthread_create(&second_thread, NULL, thread_func, NULL);
    while(1); // making main thread wait using a busy-wait (in case pthread_join) interferes
              // with pthread_detach (that's another question though: does pthread_join called
              // from another thread overlaps with pthread_detach from the same thread?)


}


任何人都可以帮我说明我忘记发布任何分配的资源吗?

2 个答案:

答案 0 :(得分:0)

使用pthread_detach()分离线程会通知pthreads库,一旦线程终止,就可以释放与此线程关联的资源。但是,您正在退出整个过程,因此Valgrind抱怨资源泄漏。虽然在流程退出时,所有资源都将在现代操作系统上清理,但Valgrind非常挑剔。

因此,如果您从exit()拨打pthread_exit(NULL);return NULL;,那么您应该看到pthreads,而不是调用thread_func() - 而不仅仅是调用线程。库释放分配的资源。

  

从另一个线程调用的pthread_join是否重叠   pthread_detach来自同一个帖子?

您无法加入已分离的线程(使用已分离的属性设置或使用pthread_detach()分离)。 pthread_detach()的文档说明了未指定

  

尝试分离已经分离的线程导致未指定   行为。

答案 1 :(得分:0)

所以,我刚刚找到了一个惊人的解决方案来解决我几天前提出的问题,我想分享一下。

只是提醒一下原始问题是什么:问题是如何在调用完整进程退出后清除线程泄漏(这不是生产代码中的实际泄漏,但这只是为了使valgrind,例如,开心!!)。

所以我提出的解决方案是:

通过为" main"创建一个线程,使主线程像任何其他线程一样。线程(我知道,这将增加内存使用量,并且它不会非常有效)。然后,实际的主线程将不断检查从任何线程发送的任何退出信号,如果是,则清除所有线程并退出。其他线程将在需要时发送退出信号,并等待实际的主线程清理它们(包括模型" main"包含预期主线程代码的线程)。

这是一个伪代码,用于举例说明我上面提到的内容:

threadId1;
threadId2;
mainThreadId;
willExit = false;
exitStatusCode;
mainThreadArgs;

exit_cleanup(exitStatusCodeArg) {
    exitStatusCode = exitStatusArg;
    willExit = true;
    while(true);
}

threadFunc1() {
    // Example thread code 1
    exit_cleanup(0);
}

threadFunc2() {
    // Example thread code 2
    if (/*some error*/)
        exit_cleanup(-1);
}

mainThreadFunc() {
    // some code (could be long, and may create side threads here)

    // by default, main thread should call exit_cleanup(0) at the end, as
    // exiting the main thread should also cancel all running threads
    exit_cleanup(0);
}

cleanUp() {
    while (willExit != false);
    for (all thread saved globally) {
        cancel and join current thread;
    }
    exit(exitStatusCode);
}

main(args) {
    mainThreadArgs = args;
    create_thread(mainThreadId, mainThreadFunc);
    cleanUp();
}



从上面的代码中,我没有看到任何理由为什么valgrind或任何其他内存泄漏检查器会抱怨任何"仍然可以访问"或者"可能丢失"泄漏。

对我的解决方案的任何更正都表示赞赏!!