Форум программистов
 
Контакты: о проблемах с регистрацией, почтой и по другим вопросам пишите сюда - alarforum@yandex.ru, проверяйте папку спам! Обязательно пройдите активизацию e-mail.

Вернуться   Форум программистов > Delphi > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail


Ответ
 
Опции темы
Старый 16.12.2016, 09:54   #1
denis76560
Форумчанин
 
Регистрация: 13.01.2010
Сообщений: 121
По умолчанию Освобождение памяти после работы потока

Здравствуйте уважаемые форумчане, недавно начал знакомство с потоками, столкнулся с такой проблемой.

имею модуль для работы с потоком такого плана:

Код:
.....................
.....................

type
  MyThread = class(TThread)
  private
    Rezult : integer;
  public

  protected
    procedure Execute; Override;
    constructor Create(CreateSuspended: Boolean);
    procedure Sync;
end;

.....................
.....................

implementation

uses MainForm;

constructor MyThread.Create(CreateSuspended: Boolean);
begin
  inherited Create(CreateSuspended);
  FreeOnTerminate := True;
  if not CreateSuspended then
    Resume;
end;

procedure MyThread.Execute;
begin
  // тут идут долгие расчеты
rezult:=RandomRange(0,456546); // RandomRange - для теста 
 Synchronize(Sync);
 Terminate; // не помогает
end;


procedure MyThread.Sync;
begin
Form1.memo1.Lines.Add(IntToStr(Rezult));
end;
с главной формы создаю поток так

Код:
Unit1.MyThread.Create(false);
Проблема в том что после работы потока он не уничтожается (насколько я понял), так как память не освобождается, вот что выходит в отчете по утечкам памяти:



если перейти по ссылке из отчета по утечке памяти то попадаю прямиком на строчку создания потока

Код:
Unit1.MyThread.Create(false);
Подскажите пожалуйста как побороть эту проблему.
denis76560 вне форума Ответить с цитированием
Старый 16.12.2016, 11:35   #2
Pavia
Лис
Старожил
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 2,050
По умолчанию

Покажите как вызываете поток? Вы уверены что он успеват уничтожиться раньше чем вы закрываете форму?
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал .
Pavia вне форума Ответить с цитированием
Старый 16.12.2016, 11:42   #3
denis76560
Форумчанин
 
Регистрация: 13.01.2010
Сообщений: 121
По умолчанию

Вызываю его так

Код:
Unit1.MyThread.Create(false);
да, конечно уверен что он успевает, ведь даже из того примера что я тут привел, результат работы уже в мемо есть при синхронизации.
denis76560 вне форума Ответить с цитированием
Старый 16.12.2016, 12:23   #4
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,260
По умолчанию

насколько я понимаю принципы ООП,
то вызывать нужно так:

Код:
myThreadTemp := Unit1.MyThread.Create(false);
а освобождать
Код:
myThreadTemp.Free;
Serge_Bliznykov вне форума Ответить с цитированием
Старый 16.12.2016, 12:42   #5
denis76560
Форумчанин
 
Регистрация: 13.01.2010
Сообщений: 121
По умолчанию

Че-то не могу сообразить как это реализовать, пробовал так:

Код:
.......
var
  myThreadTemp: array of TThread;
.......
myThreadTemp[0] := Unit1.MyThread.Create(false);
FreeAndNil(myThreadTemp[0]);
, но тогда поток вообще вываливается в Access Violation =(

а если сделать так:

Код:
   
var
 myThreadTemp: TThread;
implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
   myThreadTemp:= Unit1.MyThread.Create(false);
   myThreadTemp.Free;
то поток даже не запускается =(

а если так

Код:
   myThreadTemp:=TThread.Create(true);
   myThreadTemp:= Unit1.MyThread.Create(false);
   myThreadTemp.Free;
то поток не срабатывает, но утечка памяти все равно есть =((
denis76560 вне форума Ответить с цитированием
Старый 16.12.2016, 14:09   #6
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,260
По умолчанию

Цитата:
Сообщение от denis76560 Посмотреть сообщение
Код:
var
  myThreadTemp: array of TThread;
.......
myThreadTemp[0] :=
прежде чем обращаться к элементу динамического массива, нужно выделить память под массив.
то бишь предварительно должно быть:
Код:
SetLength( myThreadTemp, N);
где N - это число элементов массива (в данном случае - число потоков).

кстати, возможно, при изменяемом числе использовать не массив, а коллекцию ( TList и его наследники).
но можно и массив задействовать.


Цитата:
Сообщение от denis76560 Посмотреть сообщение
Код:
myThreadTemp:=TThread.Create(true);
   myThreadTemp:= Unit1.MyThread.Create(false);
   myThreadTemp.Free;
вы создаёте два раза поток (два раза выделяется память), а освобождается только один раз, вот и утечка.


Вы бы определились, когда и сколько потоков Вам нужны.
и когда их нужно очищать (освобождать память).

Последний раз редактировалось Serge_Bliznykov; 16.12.2016 в 14:11.
Serge_Bliznykov вне форума Ответить с цитированием
Старый 16.12.2016, 14:42   #7
denis76560
Форумчанин
 
Регистрация: 13.01.2010
Сообщений: 121
По умолчанию

Сам код брал отсюда http://forummaxi.ru/topic/68236-%D0%...5%D0%BC%D0%B0/

просто хотел из него сделать прокси чекер.

Дело в том что количество потоков задается пользователем
Код:
for Thread:=0 to Form1.sSpinEdit1.Value do
begin
    Unit1.MyThread.Create(false);
    Proxy:=-1;
Work:=True;
end;
далее в потоке идет проверка каждого прокси

Код:
procedure MyThread.Execute;
begin
      while Work do begin
        Cs.Enter;

           inc(Proxy);
           if Proxy<ProxysList.Count-1 then CurProxy:=Proxy else Work:=False;

..тут идет проверка самого CurProxy
.....
           Cs.Leave;
denis76560 вне форума Ответить с цитированием
Старый 16.12.2016, 14:50   #8
Aliens_wolfs
Форумчанин
 
Регистрация: 16.12.2009
Сообщений: 892
По умолчанию

Объяви переменную создания своего потока
Цитата:
var
myThreadTmp: MyThread;

for Thread:=0 to Form1.sSpinEdit1.Value do
begin
myThreadTmp:= myThread.Create(true);
myThreadTmp.Proxy:=-1; // если эта переменная объявлена в потоке
myThreadTmp.Work:=True;// если эта переменная объявлена в потоке
end;
Уничтожиться он сам по завершению ведь у тебя объявлено FreeOnTerminate := True;

Последний раз редактировалось Aliens_wolfs; 16.12.2016 в 15:00.
Aliens_wolfs вне форума Ответить с цитированием
Старый 16.12.2016, 15:26   #9
denis76560
Форумчанин
 
Регистрация: 13.01.2010
Сообщений: 121
По умолчанию

Сделал как Вы написали, все равно утечка памяти.
Вот исходник сам - там полторы строчки, http://myfiles.pro/uploads/1567305898.zzz.rar
Времени на него потерял, но все еще проблему не решил.
Буду очень благодарен за любую помощь.
denis76560 вне форума Ответить с цитированием
Старый 16.12.2016, 15:48   #10
Aliens_wolfs
Форумчанин
 
Регистрация: 16.12.2009
Сообщений: 892
По умолчанию

прерывание попробуй поставить

Код:
procedure MyThread.Execute;
begin
rezult:=RandomRange(0,456546);
Synchronize(Sync);
sleep(100); // прерывание попробуй поставить здесь
 end;
да и для проверки уничтожения сделай так
Код:
destructor MyThread.Destroy;
begin
  Synchronize(Threadfree);
  inherited;
end;

procedure MyThread.Threadfree;
begin
Showmessage('Уничтожен');
end;

Последний раз редактировалось Aliens_wolfs; 16.12.2016 в 15:53.
Aliens_wolfs вне форума Ответить с цитированием
Ответ

Здесь нужно купить рекламу за 20 тыс руб в месяц! ) пишите сюда - alarforum@yandex.ru
Без учёта ботов - 20000 человек в день, 350000 в месяц.

Опции темы


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Утечка памяти [Освобождение памяти массива] denis76560 Общие вопросы Delphi 4 27.11.2016 19:20
Освобождение памяти после запуска TOpenDialog t2skler Общие вопросы Delphi 8 14.09.2011 02:19
Освобождение памяти после исключения Syuf Общие вопросы C/C++ 10 28.05.2011 12:28
Освобождение памяти VadEr Общие вопросы Delphi 2 17.04.2009 22:23
Освобождение памяти AlexandrSid Общие вопросы Delphi 3 02.02.2009 14:45