- malloc/free in threads утечка памяти, SaneK, 13:10 , 25-Апр-03 (1)
Да, забыл, все это дело крутится на FreeBSD 4.6.2 - malloc/free in threads утечка памяти, David, 22:17 , 07-Май-03 (2)
Покажите код, хотя бы те участки (только не одну строку), где выделяется и освобождается память. Иначе вам вряд ли кто-нить сможет помочь :)А так на вскидку скорее всего происходит так, что главный поток заново выделяет память до того, как её освободил один из дочерних, указатель теряется - память тоже.
- malloc/free in threads утечка памяти, SaneK, 17:06 , 13-Май-03 (4)
Код примерно такой. ***************************************** //Основной поток typedef struct { int Поле; }pkt; ......... //packet - Глобальная переменная packet = (pkt *)calloc(Размер массива,sizeof(pkt)); i = 0; while(1) { .... Заполняем packet (packet[i].Поле = i) .... if (i == Размер массива) { pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); //db_storage_thread - Глобальная переменная pthread_create (&db_storage_thread, &attr,&my_proccess, (void *)packet); pthread_detach(db_storage_thread); packet = (pkt *)calloc(Размер массива,sizeof(pkt)); i = 0; }else{ i++; }
} /* End while */ ****************************************** //my_proccess void my_proccess(pkt *packet) { for (i=0;i < Размер массива; i++) { ...... Что то делаем с packet (сладываем каждый packet[i].поле в файл) ...... } free(packet); } ****************************** Происходит наверное именно так т.е. дочерний поток не успевает освободить память до того как основной ее заново выделит. Как такого избежать? Использовать realloc?
- malloc/free in threads утечка памяти, SaneK, 17:08 , 13-Май-03 (5)
- malloc/free in threads утечка памяти, David, 18:22 , 13-Май-03 (6)
realloc тут не поможет.самое лучшее решение - изменить дизайн программы, как уже советовал NL. Другое трудно предложить - трудно представить что может происходить, когда несколько потоков работают с одним куском памяти, один из них освобождает эту память, а другие при этом ничего не ведают. Очень странно, что программа вообще работает, не вылетая по segmentation fault. - malloc/free in threads утечка памяти, Olej, 18:32 , 14-Май-03 (7)
Было что-то такое...>void my_proccess(pkt *packet) { - вот здесь нужно было бы: 1. заблокироваться на каком-то механизме синхронизации, напр. на критическрй секции (с вызывающей программой); 2. сделать копию *packet - не указателя, а всей структуры... 3. снять блокировку, и уже можно free ... уже не нужно. 4. для всего этого лучше при запуске определить в attr повышенный приоритет потока... > > for (i=0;i < Размер массива; i++) > { > > ...... > > Что то делаем с packet (сладываем >каждый packet[i].поле в файл) > > ...... > > } > >free(packet); - а вот здесь хорошо бы посмотреть (проанализировать) код завершения free, она же не void ... вообще проверка всех кодов завершения, до уровня параноидальности ;-) - хорошая привычка. Хотя реализация эта вся - безусловно плохая. Почему вызывающая программа не могла бы создавать копию *packet для каждого порождаемого потока, например?
- malloc/free in threads утечка памяти, SaneK, 12:27 , 15-Май-03 (9)
В том то и дело что блокироваться с вызывающем программой нельзя. Основной цикл (в котором потоки порождаются) должен продолжаться без остановки. >Почему вызывающая программа не могла бы создавать копию *packet для каждого порождаемого потока, например? А как это реализовать (без остановки основного цикла)в данном случае я что то не пойму.
- malloc/free in threads утечка памяти, Olej, 11:51 , 16-Май-03 (10)
>В том то и дело что блокироваться с вызывающем программой нельзя. Основной >цикл (в котором потоки порождаются) должен продолжаться без остановки. Давайте смотреть на вещи реально: такого не бывает - хотя бы на порождение thread ваша главная ветка блокируется, а порождение thread (по накладным расходам) - это не вызов функции с передачей параметров в регистрах... Вопрос всегда в том - на сколько блокироваться? на 1мксек, 1мсек, 1сек... А дополнительное (ко времени создания thread-а) время копирования блока параметров ... вряд ли особо существенно. >>Почему вызывающая программа не могла бы создавать копию *packet для каждого порождаемого потока, например? >А как это реализовать (без остановки основного цикла)в данном случае я что то не пойму. Как-то так - в вызывающей программе: while(1) { .... //вот здесь каждый раз выделяется блок параметров pkt* packet = (pkt*)calloc(Размер массива,sizeof(pkt)); // никаких глобальных переменных... и заполняется... pthread_create (&db_storage_thread, &attr,&my_proccess, (void *)packet); ... а в функции потока: void my_proccess( pkt* packet ) { ...... Что то делаем с packet free( packet ); } но ещё лучше - я бы сразу делал дубликат блока параметров - уничтожал переданный блок, а потом что-то делал с дубликатом: void my_proccess( pkt* packet ) { pkt dubl( *packet ); free( packet ); ...... Что то делаем с dubl } Обр. вним. - это решение тоже упрощённое, и имеет дефекты синхронизации (об этом и обсуждалось в тех URL, которые я писал) - но оно уже гораздо лучше.
- malloc/free in threads утечка памяти, SaneK, 12:52 , 16-Май-03 (11)
>но ещё лучше - я бы сразу делал дубликат блока параметров - уничтожал переданный блок, а потом что-то делал с дубликатом: >void my_proccess( pkt* packet ) { > pkt dubl( *packet ); > free( packet ); > ...... > Что то делаем с dubl >} Спасибо! Вроде помогло. Но только один момент: не pkt dubl(*packet); а pkt *dubl=packet; Еще раз спасибо!
- malloc/free in threads утечка памяти, SaneK, 12:55 , 16-Май-03 (12)
Вопрос в догонку. Если я вместо такой реализации массива сделаю линейный список, плюс в скорости получу?
- malloc/free in threads утечка памяти, Olej, 17:55 , 16-Май-03 (14)
>Вопрос в догонку. Если я вместо такой реализации массива сделаю линейный список, >плюс в скорости получу? Нет, получите "минус", достаточно значительный ... я думаю. Смотрите STL - vector - вот с ним можете получить и динамичность, и скорость... Но это - C++!. Хотя gcc - до фени - вопрос вкуса юзера ;-)
- malloc/free in threads утечка памяти, Olej, 15:16 , 16-Май-03 (13)
>>но ещё лучше - я бы сразу делал дубликат блока параметров - уничтожал переданный блок, а потом что-то делал с дубликатом: >>void my_proccess( pkt* packet ) { >> pkt dubl( *packet ); >> free( packet ); >> ...... >> Что то делаем с dubl >>} > >Спасибо! Вроде помогло. Но только один момент: > >не > > pkt dubl(*packet); > >а > > pkt *dubl=packet; > >Еще раз спасибо! >Если у вас есть конструктор по-умолчанию для структуры pkt - а он всегда есть ... если вы не испортили сами, руками - то и 1-е - сработает. Правда ... подумалось ... это всё в терминологии C++, я в ней имел в виду.
- malloc/free in threads утечка памяти, NL, 11:30 , 08-Май-03 (3)
1) лучше писать прогу так: трэд, который выделил себе блок памяти, его же и освобожддает, а не поручать free другим трэдам. Так проще отследить, что откуда берется да и код становится понятнее и путаницы меньше. 2) используй realloc в основном трэде и тогда в остальных трэдах free можно выкинуть
- malloc/free in threads утечка памяти, Olej, 19:25 , 14-Май-03 (8)
>1) лучше писать прогу так: трэд, который выделил себе блок памяти, его >же и освобожддает, а не поручать free другим трэдам. Так проще > отследить, что откуда берется да и код становится понятнее и >путаницы меньше. С блоком параметров запуска thread (то, что показано в мсходном коде) - это обычно не проходит, особенно, если thread не join, да и там ... тягомутина. Так что эта задача: синхронизация доступа и разрушения блока параметров - совсем не такая частная, и возникает... Посмотрите здесь: http://qnx.org.ru/forum/viewtopic.php?topic=266&forum=4&star... http://qnx.org.ru/forum/viewtopic.php?topic=1376&forum=4 - может на что натолкнёт...
- malloc/free in threads утечка памяти, Olej, 17:01 , 19-Май-03 (15)
> При запуске приложения запускается основной поток далее по возникновению какого >то события из этого потока запускаются другие потоки использующие одну глобальную >переменную, память под которую выделяется malloc'ом в основном потоке и освобождается >free в потоках которые запускаются из основного. Доступ к этой переменной >разделяется с помощью мьютексов. Вроде прога работает, все нормально, но вот >только память используемая ей все время растет (top'ом смотрю). Вот, нашёл случайно - детальное обсуждение синхронизации ровно для того частого случая, который обсуждается: выделение блока параметров и передача его detached thread, который его и освобождает: http://qnx.org.ru/forum/viewtopic.php?topic=928&forum=4
|