Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.09.17;
Скачать: CL | DM;

Вниз

Проблема с освобождением памяти в потоке   Найти похожие ветки 

 
KyRo   (2006-08-28 13:24) [0]

Добрый день  у меня проблема
Я создаю несколько нитей одну за другой и каждая из них парсит файл после чего забивает его в базу.
Во время парсинга для добовления в базу я динамически создою
в главной процедуре каждой нити компоненты АДО

IncTr:=TAdoQuery.Create(nil);
   With IncTr do
     begin
       Connection:= DBCONNECT;
       SQL.Clear;
       SQL.Add("Select * from INCLUDE_TR_TEHPRO where 1=1");
       open;
     end;

После того как процедура выполнилась и файл записан в базу я
освобождаю их
IncTr.Free;
И после этого когда другая нить еще не закончила работу и обращается к своему компоненту появляется ошибка доступа к памяти.
Из за чего такое может быть и как освободить память ведь каждая нить создает себе свой набор компонентов для работы с базой и ошибки по идее не должно быть !
И что будет если не освобождать вообще (Тогда ошибки нету)  ?


 
StriderMan ©   (2006-08-28 13:30) [1]


> where 1=1

а это зачем?

выложи весь Execute твоего класса Thread.


 
Сергей М. ©   (2006-08-28 13:30) [2]


> IncTr


Это что ? Лок.переменная ? Поле поточного класса ?


 
KyRo   (2006-08-28 13:37) [3]


> where 1=1

Это для того что бы когда компонент переводиш в опен он не тянул данные из базы она очень большая.

Весь екзекут очень большой заманаетесь читать
вот его кусок

Reg:=Tregistry.Create;
         Reg.RootKey:=HKEY_CURRENT_USER;
         Reg.OpenKey("\SOFTWARE\LogBn\StatusHread\"+ExtractFileName(FileN[NomHr])+"\", false);
         Reg.WriteString("ProcesID",IntToStr(NomHr));
         Reg.WriteString("ProcesStatus","Begin Pars");
         Reg.WriteString("StatusOp","Run");
         Parsing_Tehpro(FileN[NomHr],NomHr,include);
         Reg.WriteString("ProcesStatus","Pars Compl");
         Reg.WriteString("StatusOp","Compl");
         Reg.Free;


Где я пишу в реестр состояние нити и запускаю процедуру для парсинга этого файла и добовление в базу

Parsing_Tehpro(FileN[NomHr],NomHr,include);

Процедура тоже большая по этому вот ее основное тело


begin
  // Создаем компонент соединения с бд
     DBCONNECT:=TADOConnection.Create(nil);  {}
   With DBCONNECT do
    begin
     ConnectionReg:=TRegistry.Create;
     ConnectionReg.RootKey:=HKEY_CURRENT_USER;
     ConnectionReg.OpenKey("\SOFTWARE\LogBn\Settings\", false);
     ConnectionString:=ConnectionReg.ReadString("ConnectionString");
     DBCONNECT.LoginPrompt:=False;
     Connected := True;
     ConnectionReg.Free;
    end;
     // Создаем компоненты для работы с бд
   TrInfo:=TAdoQuery.Create(nil);
   With TrInfo do
     begin
       Connection:= DBCONNECT;
       SQL.Clear;
       SQL.Add("Select * from TR_INFO_TEHPRO where 1=1");
       open;
     end;
   IncTr:=TAdoQuery.Create(nil);
   With IncTr do
     begin
       Connection:= DBCONNECT;
       SQL.Clear;
       SQL.Add("Select * from INCLUDE_TR_TEHPRO where 1=1");
       open;
     end;
   FindTr:=TAdoQuery.Create(nil);
   With FindTr do
     begin
       Connection:= DBCONNECT;
     end;
    //Обнуляем айди имени банкомата
    ATM_Name_Id:=0;
    //Узнаем дату транзакций из имени файла
    Date_TR:=Date_From_FileName(FileN);
    //Узнаем айди атм
    ATMNAME_From_File(FileN);
   //Создаем список и загружаем в него файл с транзакциями
     TrList:=TstringList.Create;
     TrList.LoadFromFile(FileN);
   //Создаем список для разбиения основного на блоки транзакций
     BlockList:=TstringList.Create;
     metka:=0;
      //Создаем компонент для изменений статуса
      Registr:=Tregistry.Create;
      Registr.RootKey:=HKEY_CURRENT_USER;
      Registr.OpenKey("\SOFTWARE\LogBn\StatusHread\"+ExtractFileName(FileN)+"\", false);
    // Начинаем парсить главный список
    For i := 0 to TrList.Count -1 do
      BEGIN
   //Отлавливаем начало блока транзакций
       if (ParsStFunc.TailPos(TrList.Strings[i],"->",1)>0)
         then
           begin
            metka:=1;
            BlockList.Add(TrList.Strings[i]);
           end;
      //Отлавливаем входящие транзакции
      if ((ParsStFunc.TailPos(TrList.Strings[i],"->",1)=0)and
         (ParsStFunc.TailPos(TrList.Strings[i],"<-",1)=0))
         then
           //Проверяем было ли начала блока транзакций или это неучтенная
           if (metka <> 0)and(i<>TrList.Count -1)
              then
                 BlockList.Add(TrList.Strings[i])
              else
                 begin
                  BlockList.Add(TrList.Strings[i]);
                  DbADD(BlockList);
                  BlockList.Clear;
                 end;
      //Отлавливаем конец блока транзакций
      if (ParsStFunc.TailPos(TrList.Strings[i],"<-",1)>0)
         then
           begin
             BlockList.Add(TrList.Strings[i]);
             DbADD(BlockList);
             BlockList.Clear;
             metka:=0;
           end;
      END;
    {  Registr.Free;
      BlockList.Free;
      TrList.Free;
      FindTr.Free;
      IncTr.Free;
      TrInfo.Free;
      DBCONNECT.Free; }
 end;


И вот в конце я освобождаю память.
То есть если подробно то из каждой нити я запускаю эту процедуру которая находится в отдельном модуле.


 
Сергей М. ©   (2006-08-28 13:48) [4]


> KyRo   (28.08.06 13:37) [3]


Ответь на [2]..


 
KyRo   (2006-08-28 13:52) [5]

Это локальная переменная процедуры .


 
Сергей М. ©   (2006-08-28 13:55) [6]

Какой процедуры ? Parsing_Tehpro ?


 
Ketmar ©   (2006-08-28 13:55) [7]

ой вэй. использование реестра для передачи параметров -- это инновация...


 
Ketmar ©   (2006-08-28 13:55) [8]

для передачи параметров между потоками, натурально. %-)


 
KyRo   (2006-08-28 14:04) [9]


> Сергей М. ©   (28.08.06 13:55) [6]
> Какой процедуры ? Parsing_Tehpro ?

Да


> Ketmar ©   (28.08.06 13:55) [7]
> ой вэй. использование реестра для передачи параметров --
>  это инновация...

Я не передаю через реестр параметры между потоками.
В реестр я пишу состояние потока , а из главной формы таймер переодически проверяет состояние потоков и если поток завершил работу он берет и запускает его снова на обработку другого файла.
Сделано это потому что файлов может быть неограниченое количество , а потоков всего 5 ть


 
Сергей М. ©   (2006-08-28 14:09) [10]


> KyRo   (28.08.06 14:04) [9]



> появляется ошибка доступа к памяти


И на какой конкретно строчке возникает это исключение ?


> пишу состояние потока , а из главной формы таймер переодически
> проверяет состояние потоков и если поток завершил работу
> он берет и запускает его снова на обработку другого файла


Дурней схемы не придумать)


 
Fay ©   (2006-08-28 14:13) [11]

IOCP "сделай сам" 8)


 
Ketmar ©   (2006-08-28 14:30) [12]

> [9] KyRo   (28.08.06 14:04)
ну не надо так, а? я старый, больной эльф... если моя психика не выдержит -- ты же не будешь меня содержать до смерти...


 
StriderMan ©   (2006-08-28 14:47) [13]


>    {  Registr.Free;
>       BlockList.Free;
>       TrList.Free;
>       FindTr.Free;
>       IncTr.Free;
>       TrInfo.Free;
>       DBCONNECT.Free; }

ужос!

чуть где Exception в теле процедуры - и останется куча висячих объектов!

d

try
finally
end

срочно!!


 
KyRo   (2006-08-28 14:49) [14]


> > появляется ошибка доступа к памяти
>
>
> И на какой конкретно строчке возникает это исключение ?


На любой строке другой нити где она обращается к этим компонентам которые я освободил .
То есть получается что эти компоненты не создаются в каждой нити свои , а создоются один раз и используются всеми нитями я так понимаю.


 
Ketmar ©   (2006-08-28 14:53) [15]

> [14] KyRo   (28.08.06 14:49)
> где она обращается к этим компонентам которые я освободил.
ась???



Страницы: 1 вся ветка

Текущий архив: 2006.09.17;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.034 c
4-1143902115
Ibrohimbek
2006-04-01 18:35
2006.09.17
как можно изменит рисунок меню пуск в XP


15-1156486998
Pazitron_Brain
2006-08-25 10:23
2006.09.17
Кто-нибудь ползовался Space Gate


1-1154500320
Alkid
2006-08-02 10:32
2006.09.17
GUID + Variant = Love ?


15-1156360666
LBVF
2006-08-23 23:17
2006.09.17
Откуда можно скачать Delphi 1.0


3-1152441439
Lezha
2006-07-09 14:37
2006.09.17
Ошибка при выполнении нескольких запросов через dbExpress