![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Проблема с освобождением памяти в потоке [D7, XP]
KyRo © (2006-08-28 13:24:00)Добрый день у меня проблема
Я создаю несколько нитей одну за другой и каждая из них парсит файл после чего забивает его в базу.
Во время парсинга для добовления в базу я динамически создою
в главной процедуре каждой нити компоненты АДО
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;
И после этого когда другая нить еще не закончила работу и обращается к своему компоненту появляется ошибка доступа к памяти.
Из за чего такое может быть и как освободить память ведь каждая нить создает себе свой набор компонентов для работы с базой и ошибки по идее не должно быть !
И что будет если не освобождать вообще (Тогда ошибки нету) ?
Ketmar (2006-08-28 14:53:00) [1]> [14] KyRo (28.08.06 14:49)
> где она обращается к этим компонентам которые я освободил.
ась???
KyRo (2006-08-28 14:49:00) [2]
> > появляется ошибка доступа к памяти
>
>
> И на какой конкретно строчке возникает это исключение ?
На любой строке другой нити где она обращается к этим компонентам которые я освободил .
То есть получается что эти компоненты не создаются в каждой нити свои , а создоются один раз и используются всеми нитями я так понимаю.
StriderMan (2006-08-28 14:47:00) [3]
> { Registr.Free;
> BlockList.Free;
> TrList.Free;
> FindTr.Free;
> IncTr.Free;
> TrInfo.Free;
> DBCONNECT.Free; }
ужос!
чуть где Exception в теле процедуры - и останется куча висячих объектов!
d
try
finally
end
срочно!!
Ketmar (2006-08-28 14:30:00) [4]> [9] KyRo (28.08.06 14:04)
ну не надо так, а? я старый, больной эльф... если моя психика не выдержит -- ты же не будешь меня содержать до смерти...
Fay (2006-08-28 14:13:00) [5]IOCP "сделай сам" 8)
Сергей М. (2006-08-28 14:09:00) [6]
> KyRo (28.08.06 14:04) [9]
> появляется ошибка доступа к памяти
И на какой конкретно строчке возникает это исключение ?
> пишу состояние потока , а из главной формы таймер переодически
> проверяет состояние потоков и если поток завершил работу
> он берет и запускает его снова на обработку другого файла
Дурней схемы не придумать)
KyRo (2006-08-28 14:04:00) [7]
> Сергей М. © (28.08.06 13:55) [6]
> Какой процедуры ? Parsing_Tehpro ?
Да
> Ketmar © (28.08.06 13:55) [7]
> ой вэй. использование реестра для передачи параметров --
> это инновация...
Я не передаю через реестр параметры между потоками.
В реестр я пишу состояние потока , а из главной формы таймер переодически проверяет состояние потоков и если поток завершил работу он берет и запускает его снова на обработку другого файла.
Сделано это потому что файлов может быть неограниченое количество , а потоков всего 5 ть
Сергей М. (2006-08-28 13:55:00) [8]Какой процедуры ? Parsing_Tehpro ?
Ketmar (2006-08-28 13:55:00) [9]ой вэй. использование реестра для передачи параметров -- это инновация...
Ketmar (2006-08-28 13:55:00) [10]для передачи параметров между потоками, натурально. %-)
KyRo (2006-08-28 13:52:00) [11]Это локальная переменная процедуры .
Сергей М. (2006-08-28 13:48:00) [12]
> KyRo (28.08.06 13:37) [3]
Ответь на [2]..
KyRo (2006-08-28 13:37:00) [13]
> 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;
И вот в конце я освобождаю память.
То есть если подробно то из каждой нити я запускаю эту процедуру которая находится в отдельном модуле.
StriderMan (2006-08-28 13:30:00) [14]
> where 1=1
а это зачем?
выложи весь Execute твоего класса Thread.
Сергей М. (2006-08-28 13:30:00) [15]
> IncTr
Это что ? Лок.переменная ? Поле поточного класса ?