The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

форумы  помощь  поиск  регистрация  майллист  ВХОД  слежка  RSS
"malloc/free in threads утечка памяти"
Вариант для распечатки Архивированная нить - только для чтения! 
Пред. тема | След. тема 
Форумы Программирование под UNIX (Public)
Изначальное сообщение [Проследить за развитием треда]

"malloc/free in threads утечка памяти"
Сообщение от SaneK emailИскать по авторуВ закладки on 25-Апр-03, 12:22  (MSK)

Есть приложение, написанное на Си, использующее нити, работает по следующей схеме:

  При запуске приложения запускается основной поток далее по возникновению какого то события из этого потока запускаются другие потоки использующие одну глобальную переменную, память под которую выделяется malloc'ом в основном потоке и освобождается free в потоках которые запускаются из основного. Доступ к этой переменной разделяется с помощью мьютексов. Вроде прога работает, все нормально, но вот только память используемая ей все время растет (top'ом смотрю).

Подскажите в чем может быть причина?

Спасибо.

  Рекомендовать в FAQ | Cообщить модератору | Наверх

 Оглавление

Индекс форумов | Темы | Пред. тема | След. тема
Сообщения по теме

1. "malloc/free in threads утечка памяти"
Сообщение от SaneK emailИскать по авторуВ закладки on 25-Апр-03, 13:10  (MSK)
Да, забыл, все это дело крутится на FreeBSD 4.6.2


  Рекомендовать в FAQ | Cообщить модератору | Наверх

2. "malloc/free in threads утечка памяти"
Сообщение от David emailИскать по авторуВ закладки on 07-Май-03, 22:17  (MSK)
Покажите код, хотя бы те участки (только не одну строку), где выделяется и освобождается память. Иначе вам вряд ли кто-нить сможет помочь :)

А так на вскидку скорее всего происходит так, что главный поток заново выделяет память до того, как её освободил один из дочерних, указатель теряется - память тоже.

  Рекомендовать в FAQ | Cообщить модератору | Наверх

4. "malloc/free in threads утечка памяти"
Сообщение от SaneK emailИскать по авторуВ закладки on 13-Май-03, 17:06  (MSK)
Код примерно такой.
  
*****************************************
//Основной поток

    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?

  Рекомендовать в FAQ | Cообщить модератору | Наверх

5. "malloc/free in threads утечка памяти"
Сообщение от SaneK emailИскать по авторуВ закладки on 13-Май-03, 17:08  (MSK)
Забыл, pkt - глобальная
  Рекомендовать в FAQ | Cообщить модератору | Наверх

6. "malloc/free in threads утечка памяти"
Сообщение от David emailИскать по авторуВ закладки on 13-Май-03, 18:22  (MSK)
realloc тут не поможет.

самое лучшее решение - изменить дизайн программы, как уже советовал NL.

Другое трудно предложить - трудно представить что может происходить, когда несколько потоков работают с одним куском памяти, один из них освобождает эту память, а другие при этом ничего не ведают. Очень странно, что программа вообще работает, не вылетая по segmentation fault.

  Рекомендовать в FAQ | Cообщить модератору | Наверх

7. "malloc/free in threads утечка памяти"
Сообщение от Olej emailИскать по авторуВ закладки on 14-Май-03, 18:32  (MSK)
Было что-то такое...

>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 для каждого порождаемого потока, например?

  Рекомендовать в FAQ | Cообщить модератору | Наверх

9. "malloc/free in threads утечка памяти"
Сообщение от SaneK emailИскать по авторуВ закладки on 15-Май-03, 12:27  (MSK)
В том то и дело что блокироваться с вызывающем программой нельзя. Основной цикл (в котором потоки порождаются) должен продолжаться без остановки.

>Почему вызывающая программа не могла бы создавать копию *packet для каждого порождаемого потока, например?
А как это реализовать (без остановки основного цикла)в данном случае я что то не пойму.

  Рекомендовать в FAQ | Cообщить модератору | Наверх

10. "malloc/free in threads утечка памяти"
Сообщение от Olej emailИскать по авторуВ закладки on 16-Май-03, 11:51  (MSK)
>В том то и дело что блокироваться с вызывающем программой нельзя. Основной
>цикл (в котором потоки порождаются) должен продолжаться без остановки.

Давайте смотреть на вещи реально: такого не бывает - хотя бы на порождение 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, которые я писал) - но оно уже гораздо лучше.

  Рекомендовать в FAQ | Cообщить модератору | Наверх

11. "malloc/free in threads утечка памяти"
Сообщение от SaneK emailИскать по авторуВ закладки on 16-Май-03, 12:52  (MSK)
>но ещё лучше - я бы сразу делал дубликат блока параметров - уничтожал переданный блок, а потом что-то делал с дубликатом:
>void my_proccess( pkt* packet ) {
>  pkt dubl( *packet );
>  free( packet );
>  ......
>  Что то делаем с dubl
>}

Спасибо! Вроде помогло. Но только один момент:

не

pkt dubl(*packet);

а

pkt *dubl=packet;

Еще раз спасибо!

  Рекомендовать в FAQ | Cообщить модератору | Наверх

12. "malloc/free in threads утечка памяти"
Сообщение от SaneK emailИскать по авторуВ закладки on 16-Май-03, 12:55  (MSK)
Вопрос в догонку. Если я вместо такой реализации массива сделаю линейный список, плюс в скорости получу?
  Рекомендовать в FAQ | Cообщить модератору | Наверх

14. "malloc/free in threads утечка памяти"
Сообщение от Olej emailИскать по авторуВ закладки on 16-Май-03, 17:55  (MSK)
>Вопрос в догонку. Если я вместо такой реализации массива сделаю линейный список,
>плюс в скорости получу?

Нет, получите "минус", достаточно значительный ... я думаю.
Смотрите STL - vector - вот с ним можете получить и динамичность, и скорость...
Но это - C++!.
Хотя gcc - до фени - вопрос вкуса юзера ;-)

  Рекомендовать в FAQ | Cообщить модератору | Наверх

13. "malloc/free in threads утечка памяти"
Сообщение от Olej emailИскать по авторуВ закладки on 16-Май-03, 15:16  (MSK)
>>но ещё лучше - я бы сразу делал дубликат блока параметров - уничтожал переданный блок, а потом что-то делал с дубликатом:
>>void my_proccess( pkt* packet ) {
>>  pkt dubl( *packet );
>>  free( packet );
>>  ......
>>  Что то делаем с dubl
>>}
>
>Спасибо! Вроде помогло. Но только один момент:
>
>не
>
> pkt dubl(*packet);
>

>
> pkt *dubl=packet;
>
>Еще раз спасибо!
>

Если у вас есть конструктор по-умолчанию для структуры pkt - а он всегда есть ... если вы не испортили сами, руками - то и 1-е - сработает.

Правда ... подумалось ... это всё в терминологии C++, я в ней имел в виду.

  Рекомендовать в FAQ | Cообщить модератору | Наверх

3. "malloc/free in threads утечка памяти"
Сообщение от NL emailИскать по авторуВ закладки on 08-Май-03, 11:30  (MSK)
1) лучше писать прогу так: трэд, который выделил себе блок памяти, его же и освобожддает, а не поручать free другим трэдам. Так проще  отследить, что откуда берется да и код становится понятнее и путаницы меньше.
2) используй realloc в основном трэде и тогда в остальных трэдах free можно выкинуть
  Рекомендовать в FAQ | Cообщить модератору | Наверх

8. "malloc/free in threads утечка памяти"
Сообщение от Olej emailИскать по авторуВ закладки on 14-Май-03, 19:25  (MSK)
>1) лучше писать прогу так: трэд, который выделил себе блок памяти, его
>же и освобожддает, а не поручать free другим трэдам. Так проще
> отследить, что откуда берется да и код становится понятнее и
>путаницы меньше.

С блоком параметров запуска thread (то, что показано в мсходном коде) - это обычно не проходит, особенно, если thread не join, да и там ... тягомутина. Так что эта задача: синхронизация доступа и разрушения блока параметров - совсем не такая частная, и возникает...

Посмотрите здесь:
http://qnx.org.ru/forum/viewtopic.php?topic=266&forum=4&start=0&show_all=1
http://qnx.org.ru/forum/viewtopic.php?topic=1376&forum=4
- может на что натолкнёт...


  Рекомендовать в FAQ | Cообщить модератору | Наверх

15. "malloc/free in threads утечка памяти"
Сообщение от Olej emailИскать по авторуВ закладки on 19-Май-03, 17:01  (MSK)
>  При запуске приложения запускается основной поток далее по возникновению какого
>то события из этого потока запускаются другие потоки использующие одну глобальную
>переменную, память под которую выделяется malloc'ом в основном потоке и освобождается
>free в потоках которые запускаются из основного. Доступ к этой переменной
>разделяется с помощью мьютексов. Вроде прога работает, все нормально, но вот
>только память используемая ей все время растет (top'ом смотрю).

Вот, нашёл случайно - детальное обсуждение синхронизации ровно для того частого случая, который обсуждается: выделение блока параметров и передача его detached thread, который его и освобождает:
http://qnx.org.ru/forum/viewtopic.php?topic=928&forum=4

  Рекомендовать в FAQ | Cообщить модератору | Наверх


Удалить

Индекс форумов | Темы | Пред. тема | След. тема
Пожалуйста, прежде чем написать сообщение, ознакомьтесь с данными рекомендациями.




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру