Nejsem si jistý, jestli vás to stále zajímá, ale momentálně řeším podobnou situaci. Vlákna, která používají pthread_exit
způsobit, že valgrind hlásí dosažitelné bloky. Důvod se zdá být docela dobře vysvětlen zde:
https://bugzilla.redhat.com/show_bug.cgi?id=483821
V podstatě to vypadá pthread_exit
způsobí dlopen
který není nikdy explicitně vyčištěn při ukončení procesu.
Následující minimální testovací případ vykazuje chování, které popisujete:
#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
ukazuje 5 bloků alokovaných z funkcí volaných pthread_exit()
který je uvolněný, ale stále dosažitelný při ukončení procesu. Pokud pthread_exit(0);
je nahrazeno return 0;
, 5 bloků není přiděleno.
Pokud však otestujete vytváření a spojování velkého počtu vláken, zjistíte, že množství neuvolněné paměti použité při ukončení ne zvýšit. To a skutečnost, že je stále dosažitelné, naznačuje, že právě vidíte podivnost implementace glibc. Několik funkcí glibc přiděluje paměť pomocí malloc()
při prvním volání, které si ponechávají přidělené po zbytek životnosti procesu. glibc se neobtěžuje uvolnit tuto paměť při ukončení procesu, protože ví, že proces je stejně stržen – bylo by to jen plýtvání cykly CPU.
Používáš náhodou C++? Pro upřesnění – váš zdrojový soubor končí znakem .c
a kompilujete jej s gcc
, nikoli g++
?
Zdá se poměrně pravděpodobné, že vaše funkce přiděluje prostředky, u kterých očekáváte, že budou automaticky vyčištěny, když se funkce vrátí. Místní objekty C++ jako std::vector
nebo std::string
udělejte to a jejich destruktory se pravděpodobně nespustí, pokud zavoláte pthread_exit
, ale bude vyčištěno, pokud se právě vrátíte.
Dávám přednost vyhnout se nízkoúrovňovým rozhraním API, jako je pthread_exit
a vždy se vraťte z funkce vlákna, kde je to možné. Jsou ekvivalentní, kromě pthread_exit
je de-facto konstrukce řízení toku, která obchází jazyk, který používáte, ale return
ne.