Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 27.12.2012, 11:08
Pcrepair
 
Сообщения: n/a
По умолчанию Возможные проблемы с TThread при закачке страниц

Добрый день.
Есть функция вида function LoadPage(const Url:string):string; для закачки страниц на базе idHHP.Get, которая обеспечивает:
- закачку страниц с фреймами
- закачку страниц по HTTPs
- смену Request.UserAgent (доп. функция) по Random из списка агентов
- подавление исключений в коде idHHP.Get с записью в лог причин
- вывод сообщений о утечке памяти при закрытии Арр
Сама по себе функция работает нормально, загружает все страницы и без утечки памяти.

Есть код запуска этой функции в многопоточном режиме:
Код:
+++++++++++++++++++++++++++++++++++++++
unit Main;
....
implementation
{$R *.dfm}
uses uLoadPage,uGlobalVar;

(*нажимает эту кнопку и понеслось*)
procedure TMainForm.Btn_StartLoadURLsClick(Sender: TObject);
var
UrlList:TStringList; (*эквивалент передаваемого массива строк из ПМ*)
i:integer;
Url:string; (*строка = УРЛ из массива*)
begin
   UrlList:=TStringList.Create;
   UrlList.Text:=Mm_InsSMUrls.Text; (*ввод массива строк УРЛ*)
     (*----ЦИКЛ мульти закачки страниц по числу УРЛ в Mm_InsSMUrls---*)
     for i := 0 to UrlList.Count-1 do
       begin
          Url:=UrlList[i]; (*передача УРЛ*)
          Loader(Url); (*вызов процедуры запуска потока закачки страницы*)
          Sleep(10);  (*страховка от перегрева процессора а также от толпы потоков, которые мешают друг другу?*)
       end;
   FreeAndNil(UrlList);
end;
+++++++++++++++++++++++++++++++++++++++
unit uLoadPage;
interface
uses SysUtils, uThreadLoader, Classes;
Procedure Loader(Url:string);
implementation
Procedure Loader(Url:string);
var ThreadLdr: TLoader;
begin
    ThreadLdr:=Tloader.Create(True);
    ThreadLdr.Priority:=tpNormal;   
    ThreadLdr.FreeOnTerminate:=True;
    ThreadLdr.Url:=Url;
    ThreadLdr.Start;
  end;
end.
+++++++++++++++++++++++++++++++++++++++
unit uThreadLoader;
interface
uses
  System.Classes, idHTTP, SysUtils, Dialogs;
type
  TLoader = class(TThread)
  private
     FUrl:string;
     FHtml:string;
    { Private declarations }
  protected
    procedure Execute; override;
    procedure CallStore;
    function LoadHtmlCode(const Url:string):string;
  public
    property Url: string read FUrl write FUrl;  (*свойство класа, доступное для всей программы*)
    property Html: string read FHtml write FHtml;
  end;

implementation
uses uPageLoader, uLoadPage, uGlobalVar;

function TLoader.LoadHtmlCode(const Url:string):string;
begin
  Result:=LoadPage(Url); (*вызываем функцию загрузки страницы из uPageLoader*)
end;

procedure TLoader.CallStore;
begin
   gStore.Add(Html); (*ввод новой строки в ГлобПерем*)
end;

procedure TLoader.Execute;
begin
   Html:=LoadHtmlCode(Url);  (*загрузка страницы в Поле Класса(свойство)*)
    CS.Enter;  (*вход в КС*)
       CallStore; (*передаем результат в ГП*)
    Cs.Leave;  (*выход из КС*)
end;

end.
++++++++++++++++++++++++++++++++++++++++++++
unit uPageLoader;
interface
uses Classes, SysUtils, idHTTP, StrUtils, IdSSL, IdSSLOpenSSL;
    function LoadPage(const Url:string):string;  (*Основная функция Юнита*)
    procedure ErrorLog(Url:string);
    function LoadHtmlPage(const PageUrl:string):string;
    function DelJS(const Code:string):string;
    function RestoreFrame(const Code:string):string;
    function RestoreFullUrl(const Code:string; const RootUrl:string):string;
    function GetRandomUserAgent: string;
    var
    Loader:TidHTTP;
    SSL:TIdSSLIOHandlerSocketOpenSSL;

implementation
тут много чего, но все работает, смотри в начало
end.
++++++++++++++++++++++++++++++++++++++++++++
unit uGlobalVar;
interface
uses Classes, SysUtils, SyncObjs;
var
gStore: TStringList=nil; (*ГП для хранения закачанных страниц*)
CS:TCriticalSection; (*используем КС для передачи результата в основной поток*)
implementation

initialization
   gStore:=TStringList.Create;
   gStore.Duplicates:=dupAccept;
   gStore.Sorted:=False;
   Cs:=TCriticalSection.Create;
finalization
  FreeAndNil(gStore);
  FreeAndNil(CS);
end.
++++++++++++++++++++++++++++++++++++++++++++
Результат:
В режиме отладки видно что возникает множество самых различных ошибок:
- First chance exception at $00407466. Exception class $C0000005 with message 'access violation at 0x00407466: read of address 0x000000a4'. Process Loader_VER06.exe (2012)
- First chance exception at $7C812AFB. Exception class EIdHTTPProtocolException with message 'Set-Cookie: dle_password=deleted; expires=Tue, 27-Dec-2011 20:37:50 GMT; path=/; domain=.freeseller.ru; httponly'. Process Loader_VER06.exe (2012)
First chance exception at $00629F8C. Exception class $C0000005 with message 'access violation at 0x00629f8c: read of address 0x00000148'. Process Loader_VER06.exe (2012)
- First chance exception at $7C812AFB. Exception class EOSError with message
'System Error. Code: 123. Синтаксическая ошибка в имени файла, имени папки или метке тома'.
Process Loader_VER06.exe (2012)
- First chance exception at $7C812AFB. Exception class EIdNotASocket with message
'Socket Error # 10038
Socket operation on non-socket.'.
Process Loader_VER06.exe (2012)

В рабочем режиме, за счет подавления исключений, все это конечно не вылазит, но:
- закачиваются не все страницы(хотя все УРЛ валидные и функцией закачки закачиваются без вопросов)
- после закрытия Арр выводится сообщение о многочисленных маленьких утечках памяти

По теории потоки не должны пересекаться. каждый имеет свою память. вывод результата через КС. такое впечетление что потоки как то мешают друг другу
Внимание!!! Вопрос: в чем может быть причина появления исключений и утечки памяти именно в режиме многопотоковой закачки?
Ответить с цитированием
  #2  
Старый 27.12.2012, 12:01
Аватар для M.A.D.M.A.N.
M.A.D.M.A.N. M.A.D.M.A.N. вне форума
Sir Richard Abramson
 
Регистрация: 05.04.2008
Сообщения: 5,505
Версия Delphi: XE10
Репутация: выкл
По умолчанию

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

По поводу AV вылавливай в отладчике, возможно, какой-то объект мертвый.
__________________
— Как тебя понимать?
— Понимать меня не обязательно. Обязательно меня любить и кормить вовремя.


На Delphi, увы, больше не программирую.
Рекомендуемая литература по программированию
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 02:30.


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2025