我有一个可连接的pthread runner函数,定义如下:

void *sumOfProducts(void *param)
{
...
pthread_exit(0);
}

这根线应该连接主线.

每当我通过Valgrind运行我的程序时,我都会得到following leaks分:

LEAK SUMMARY:
   definitely lost: 0 bytes in 0 blocks
   indirectly lost: 0 bytes in 0 blocks
     possibly lost: 0 bytes in 0 blocks
   still reachable: 968 bytes in 5 blocks
        suppressed: 0 bytes in 0 blocks

ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 15 from 10)

我查看了手册页上的pthreads,上面写着:

  The new thread terminates in one of the following ways:

   * It  calls  pthread_exit(3),  specifying  an exit status value that is
     available  to  another  thread  in  the  same  process   that   calls
     pthread_join(3).

   * It  returns  from  start_routine().   This  is  equivalent to calling
     pthread_exit(3) with the value supplied in the return statement.

   * It is canceled (see pthread_cancel(3)).

   * Any of the threads in the process calls exit(3), or the  main  thread
     performs  a  return  from main().  This causes the termination of all
     threads in the process.

神奇的是,当我用返回语句the leaks disappeared替换pthread_exit()时.

return(NULL);

我的实际问题有三个方面:

  1. 有人能解释为什么返回声明没有泄露信息吗?
  2. 在退出线程方面,这两个语句之间是否存在一些基本的区别?
  3. 如果是这样,什么时候应该 Select 其中一个?

推荐答案

以下最小测试用例展示了您描述的行为:

#include <pthread.h>
#include <unistd.h>

void *app1(void *x)
{
    sleep(1);
    pthread_exit(0);
}

int main()
{
    pthread_t t1;

    pthread_create(&t1, NULL, app1, NULL);
    pthread_join(t1, NULL);

    return 0;
}

valgrind --leak-check=full --show-reachable=yes显示了从pthread_exit()调用的函数中分配的5个块,这些函数未绑定,但在进程退出时仍然可以访问.如果将pthread_exit(0);替换为return 0;,则不分配5个块.

但是,如果您测试创建和连接大量线程,您会发现在退出时使用的未绑定内存量确实会增加.这一点,以及它仍然可以访问的事实,表明您只是看到了glibc实现的一个奇怪之处.一些glibc函数在第一次调用时分配malloc()个内存,并在进程生命周期的剩余时间内保持分配.glibc不会在进程退出时释放内存,因为它知道进程无论如何都会被 destruct ——这只是浪费CPU周期.

Linux相关问答推荐

是否可以在Bash正则表达式中排除?

AWK:按第一列匹配两个文件不起作用

从 MariaDB 连接到 Oracle 时出现错误消息libsqora.so.11.1:找不到文件

为什么当凭证助手设置为存储 SSH 远程存储库时 git pull 不使用 .git-credentials

命令应在终端关闭后继续运行

获取S3路径的linux命令

为什么 fork() 在 setsid() 之前

如何在 shell 脚本中只读取一个字符

在 Python 上模拟鼠标点击

如何更改某些文件模式/扩展名的权限?

Bash 命令 :(){ :|:& };: 将产生进程导致内核死亡.你能解释一下语法吗?

什么是最有效的不区分大小写的 grep 用法?

如何使目录下的所有文件在linux上可读?

无法在 Android Studio 中清理项目

在 bash 中检测公共 IP 地址的方法

如何在第一个错误时停止 xargs?

在 Linux 上用 C 语言读写串口

什么是 linux 脚本中的 start-stop-daemon?

Linux 上的最大文件/目录数?

当系统说当前在进程中使用时,如何在linux中删除用户