pthread_create, pthread_exit - память не удаляется

Все о программировании под *nix
unq
Интересующийся
Сообщения: 53
Зарегистрирован: 05 июл 2004, 00:58

pthread_create, pthread_exit - память не удаляется

Сообщение unq »

написал небольшую программку и результят меня смущает, вот исходник:

Код: Выделить всё

#include <iostream>
#include <sstream>
#include <pthread>
#include <sys>
#include <unistd>

static int status=0;

void* entry(void* param)
{	

	char *p = new char[1024*1024];
	delete []p;
	sleep(1);
	
	cout<<"exit thread "<<*((pthread_t*)param)<<"\r\n";
	
	pthread_exit((void*)&status);
}


int main(int argc, char* argv[])
{
	int i;
	cout<<"kren\r\n";
	cout<<"pid = "<<getpid()<<"\r\n";
	cout<<"kren\r\n";
	
	char a;
	cin>>a;
	
	int stackSize = 1024 * 256;
	
	pthread_attr_t attr;
		if(pthread_attr_init(&attr) != 0) {
			cout<<"pthread_attr_init error\r\n";
		} 
		pthread_attr_setstacksize(&attr,(size_t)stackSize);
		pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
	
	pthread_t tr[200];

	for(i=0;i<200;i++){
		int r = pthread_create(
			&(tr[i]),
			&attr,
			entry,
			(void*)&(tr[i]));
		if(r != 0 ){
			cout<<"pthread_create error\r\n";
		}
		cout<<"create thread ("<<tr[i]<<") num "<<i<<"\r\n";
		if(i == 100)
			sleep(5);
	}
	
	sleep(2);
	pthread_attr_destroy (&attr);
	cout<<"end\r\n";
	cin>>a;
	return 0;
}
при запуске программы смотрю top -p PID:
VIRT = 2480, RES = 592, SWAP = 1888

затем создаются потоки и выходят(main еще работает), опять смотрю top -p PID:
VIRT = 28904, RES = 1536, SWAP = 26m

в чем дело? я думад что после выхода потоков я должен увидеть тоже самое что и до их создания?

System:
CentOS release 4.2 (Final), 2.6.9-22.EL, gcc version 3.4.4 20050721 (Red Hat 3.4.4-2)

Аватара пользователя
exe
Неотъемлемая часть форума
Сообщения: 860
Зарегистрирован: 28 ноя 2003, 21:08
Откуда: Минск

Сообщение exe »

Скорее всего это кэширование.

Причем память не всегда возвращается в систему, а только если она по адресу последняя. Смотри sbrk().

Если ищешь потерю памяти, используй valgrind на linux.

unq
Интересующийся
Сообщения: 53
Зарегистрирован: 05 июл 2004, 00:58

Сообщение unq »

во-первых, спасибо за ответ.
я не ищу leaks. В том коде что я привел только один оператор new в функции потока, но без него работает все так-же.
если честно то я не понял как работать с функцией sbrk or brk в смысле если у меня показывается кэш - то как от него избавится. Если не сложно - подскажите , можно типа примерчик.

unq
Интересующийся
Сообщения: 53
Зарегистрирован: 05 июл 2004, 00:58

Сообщение unq »

огромное спасибо за такой ответ!!! удивило
но теперь по-существу:
задача была понять, почему пямять до создания не равна памяти после создания и удаления потоков. sleep() стоит только лишь для того чтобы позволить потоку "повисеть" хотя бы секунду - это ерунда, без которой я получаю тотже результат - я имею ввиду top показывает значительное увеличения пямяти примерно на 20М.
Ваш код конечно смотрится приятнее(что было плохого в функциях attr? - почему вы их удалили? :) ), но выдает тот-же результат:

before create threads:
VIRT RES
4100 592

after deleting threads:
VIRT RES
34836 728

не уверен что следующая фраза понравится кому-нить тут :), но тем не мение:
аналогичный тест под Win32 выдает результат на нуль, before = after, по крайней мере так показывает TaskMan. Вот и хотелось добиться того-же рузультата

unq
Интересующийся
Сообщения: 53
Зарегистрирован: 05 июл 2004, 00:58

Сообщение unq »

Aleksey Kondratenko, за последний пост огромное спасибо!!!!
вот за эту часть:
Не вижу ничего плохого в том, что NPTL pool'ирует стеки потоков. В том что "лишняя" память это стеки потоков можно убедиться посмотрев /proc/<pid>/smaps (или maps если ядро не очень новое). Если ядро поддерживает /proc/<pid>/smaps, то хорошо видно, что эти стеки потребляют совсем чуть-чуть реальной памяти.

Пул стеков позволяет NPTL быстрее создавать потоки, т.к. часть ресурсов необходимых потоку (стек) пулируется.

Если вдруг очень нужно, чтобы стеки не пулировались (хотя я не понимаю, зачем это необходимо) следует посмотреть исходники NPTL, или обратиться в список рассылки glibc.
я не ставил своей целью убрать (в случае если это не баг, естественно!!!) это "дело" - просто хотелось понять почуму так происходит!!!

однако хотелось бы услышать ваш комментарий по этой фразе:
А атрибут PTHREAD_CREATE_DETACHED, был убран как вредный.

unq
Интересующийся
Сообщения: 53
Зарегистрирован: 05 июл 2004, 00:58

Сообщение unq »

Я имел в виду что он вредный в контексте этой конкретной задачи.
В последней "измерительной точке" нам нужно чтобы все потоки были мертвы. Проконтролировать это проще через pthread_join
ага. ясненько - а то я было испугался что с отсоединенными потоками какая-то ерунда :)

Алексей, огромное спасибо - вы мне очень помогли!

Ответить