Следующий минимальный тестовый пример демонстрирует поведение, которое вы описываете:
#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
показывает 5 блоков, выделенных из функций, вызываемых pthread_exit()
, которые являются несвободными, но все же достижимыми при выходе из процесса. Если pthread_exit(0);
заменено на return 0;
, 5 блоков не выделяются.
Однако, если вы протестируете создание и объединение большого количества потоков, вы обнаружите, что количество неосвобожденной памяти, используемой при выходе, увеличивается , а не . Это и тот факт, что он все еще доступен, указывает на то, что вы просто видите странность реализации glibc. Несколько функций glibc выделяют память с malloc()
при первом вызове, который они сохраняют для оставшейся части времени жизни процесса. glibc не заботится о том, чтобы освободить эту память при выходе из процесса, поскольку знает, что процесс все равно прерывается - это просто пустая трата циклов процессора.