使用条件变量时检测到的线程泄漏而不是使用Pthread的Join()

发布于 2025-02-03 08:47:38 字数 1984 浏览 2 评论 0原文

我是PTHread同步的新手,在Google中搜索了“ Pthread条件变量”,并从PDF中获取一个示例: https://pages.cs.wisc.edu/~remzi/ostep/threads-cv.pdf

示例代码如下,其目的是“使用条件变量和变量完成实现pthread_join()>”(我理解):

// https://godbolt.org/z/8rPMq54K8
#include <stdio.h>
#include <pthread.h>

volatile int done  = 0;
pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t c  = PTHREAD_COND_INITIALIZER;
void thr_exit() {
    pthread_mutex_lock(&m);
    done = 1;
    pthread_cond_signal(&c);
    pthread_mutex_unlock(&m);
}
void *child(void *arg) {
    printf("child\n");
    thr_exit();
    return NULL;
}
void thr_join() {
    pthread_mutex_lock(&m);
    while (done == 0)
    {
        pthread_cond_wait(&c, &m);
    }
    pthread_mutex_unlock(&m);
}

int main(int argc, char *argv[])
{
    printf("parent: begin\n");
    pthread_t p;
    pthread_create(&p, NULL, child, NULL);
    thr_join();
    printf("parent: end\n");
    return 0;
}

与:一起编译:

clang++ main.cpp -fsanitize=thread -g -fno-omit-frame-pointer

运行它将请参阅报告的“线程泄漏”:

(base) ➜  case12 git:(main) ✗ ./a.out
a.out(71120,0x10433c580) malloc: nano zone abandoned due to inability to preallocate reserved vm space.
parent: begin
child
parent: end
==================
WARNING: ThreadSanitizer: thread leak (pid=71120)
  Thread T1 (tid=1365892, finished) created by main thread at:
    #0 pthread_create <null>:74364228 (libclang_rt.tsan_osx_dynamic.dylib:arm64e+0x2bbe8)
    #1 main main_v4.cpp:31 (a.out:arm64+0x100003e38)

SUMMARY: ThreadSanitizer: thread leak main_v4.cpp:31 in main
==================
ThreadSanitizer: reported 1 warnings

此C ++代码真的是线程泄漏,还是TSAN的误报报告?

I'm new to pthread synchronization, searched "pthread condition variable" in google and grab an example from the pdf: https://pages.cs.wisc.edu/~remzi/OSTEP/threads-cv.pdf .

The example code is as follow, whose purpose is "use condition variable and a variable done to implement pthread_join()" (as I understand):

// https://godbolt.org/z/8rPMq54K8
#include <stdio.h>
#include <pthread.h>

volatile int done  = 0;
pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t c  = PTHREAD_COND_INITIALIZER;
void thr_exit() {
    pthread_mutex_lock(&m);
    done = 1;
    pthread_cond_signal(&c);
    pthread_mutex_unlock(&m);
}
void *child(void *arg) {
    printf("child\n");
    thr_exit();
    return NULL;
}
void thr_join() {
    pthread_mutex_lock(&m);
    while (done == 0)
    {
        pthread_cond_wait(&c, &m);
    }
    pthread_mutex_unlock(&m);
}

int main(int argc, char *argv[])
{
    printf("parent: begin\n");
    pthread_t p;
    pthread_create(&p, NULL, child, NULL);
    thr_join();
    printf("parent: end\n");
    return 0;
}

Compiled with:

clang++ main.cpp -fsanitize=thread -g -fno-omit-frame-pointer

Running it will see "thread leak" reported:

(base) ➜  case12 git:(main) ✗ ./a.out
a.out(71120,0x10433c580) malloc: nano zone abandoned due to inability to preallocate reserved vm space.
parent: begin
child
parent: end
==================
WARNING: ThreadSanitizer: thread leak (pid=71120)
  Thread T1 (tid=1365892, finished) created by main thread at:
    #0 pthread_create <null>:74364228 (libclang_rt.tsan_osx_dynamic.dylib:arm64e+0x2bbe8)
    #1 main main_v4.cpp:31 (a.out:arm64+0x100003e38)

SUMMARY: ThreadSanitizer: thread leak main_v4.cpp:31 in main
==================
ThreadSanitizer: reported 1 warnings

Is this C++ code really a thread leak, or just a false positive report from tsan?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

山有枢 2025-02-10 08:47:40

此C ++代码真的是线程泄漏,还是TSAN的假阳性报告?

这确实是一个线程泄漏,这是由于您无法实现pthread_join()的替代品。至少不以任何便携式方式或仅基于C ++(或C)和Pthreads规范。该程序启动一个线程,在终止之前既不会分离也不会加入。这是线程泄漏。

该程序确实成功,可靠地等待终止,直到子线程提供了thr_exit()的证据,但这并不能替代加入子线程。

Is this C++ code really a thread leak, or just a false positive report from tsan?

It is really a thread leak, arising from the fact that you cannot implement a substitute for pthread_join(). At least, not in any portable way or based only on the C++ (or C) and pthreads specifications. The program starts a thread and neither detaches nor joins it before terminating. That's a thread leak.

The program does successfully and reliably wait to terminate until the child thread provides evidence that it has called thr_exit(), but that is not a substitute for joining the child thread.

辞旧 2025-02-10 08:47:40

(这不是答案,只是我可以编写的解决方案代码,在阅读John Bollinger的答案之后。)

解决方案1:

int main(int argc, char *argv[])
{
    printf("parent: begin\n");
    pthread_t p;
    pthread_create(&p, NULL, child, NULL);
    pthread_detach(p);  // !! new added line
    thr_join();
    printf("parent: end\n");
    return 0;
}

解决方案2:

void *child(void *arg) {
    pthread_detach(pthread_self()); //!! new added line
    printf("child\n");
    thr_exit();
    return NULL;
}

(This is not an answer, just the solution code that I can write, after reading John Bollinger's answer.)

Solution 1:

int main(int argc, char *argv[])
{
    printf("parent: begin\n");
    pthread_t p;
    pthread_create(&p, NULL, child, NULL);
    pthread_detach(p);  // !! new added line
    thr_join();
    printf("parent: end\n");
    return 0;
}

Solution2:

void *child(void *arg) {
    pthread_detach(pthread_self()); //!! new added line
    printf("child\n");
    thr_exit();
    return NULL;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文