Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

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

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 27.12.2012, 11:05   #1
Pcrepair
Форумчанин
 
Регистрация: 04.01.2011
Сообщений: 263
По умолчанию Возможные проблемы с 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.
++++++++++++++++++++++++++++++++++++++++++++
Pcrepair вне форума Ответить с цитированием
Старый 27.12.2012, 11:06   #2
Pcrepair
Форумчанин
 
Регистрация: 04.01.2011
Сообщений: 263
По умолчанию

Результат:
В режиме отладки видно что возникает множество самых различных ошибок:
- 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)

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

По теории потоки не должны пересекаться. каждый имеет свою память. вывод результата через КС. такое впечетление что потоки как то мешают друг другу
Внимание!!! Вопрос: в чем может быть причина появления исключений и утечки памяти именно в режиме многопотоковой закачки?
Pcrepair вне форума Ответить с цитированием
Старый 27.12.2012, 13:13   #3
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,528
По умолчанию

В одном потоке все работает => LoadPage не потокобезоасна. (использует и меняет не локальные данные).
Код:
function TLoader.LoadHtmlCode(const Url:string):string;
begin
Result:=LoadPage(Url); (*вызываем функцию загрузки страницы из uPageLoader*)
end;

unit uPageLoader;
interface
uses Classes, SysUtils, idHTTP, StrUtils, IdSSL, IdSSLOpenSSL;
  function LoadPage(const Url:string):string;  (*Основная функция Юнита*)

  var
  Loader:TidHTTP;
  SSL:TIdSSLIOHandlerSocketOpenSSL;
Цитата:
По теории потоки не должны пересекаться. каждый имеет свою память.
а на практике
использование одного Loader, SSL для ВСЕХ потоков.

> тут много чего, но все работает, смотри в начало

тоже все глобальные объекты едины для всех потоков.
программа — запись алгоритма на языке понятном транслятору
evg_m вне форума Ответить с цитированием
Старый 27.12.2012, 22:14   #4
Pcrepair
Форумчанин
 
Регистрация: 04.01.2011
Сообщений: 263
По умолчанию

Цитата:
Сообщение от evg_m Посмотреть сообщение
В одном потоке все работает => LoadPage не потокобезоасна. (использует и меняет не локальные данные).
так, это понятно. кое кто кое где намекал, что idHTTP в потоках лучше не использовать.

может ICS получше будет? там вроде асинхронность врожденная. но вот как там с выбором кодировки? в последней версии ИНДИ эту проблему почти решили. и как там с HTTPs? есть возможность закачивать страницы по SSL?
Pcrepair вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Проблема при закачке скрипта на сервер Taylor1990 JavaScript, Ajax 3 15.11.2012 19:03
При освобождении обьекта TThread, он вешает всю программу. При этом код Execute у TThread уж выполнился.. Человек_Борща Общие вопросы Delphi 23 30.11.2011 09:18
Проблемы кодировки при создании .CFM страниц в Dreamweaver CS3 bp-alex Софт 1 01.05.2010 17:51
Как узнать скорость при закачке tIdHttp.get? Altera Работа с сетью в Delphi 7 09.04.2009 11:27
Заблокировать запуск exe из IE при закачке Igoressicus Помощь студентам 5 19.02.2009 11:59