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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 13.02.2012, 15:10   #1
Зод
Форумчанин
 
Регистрация: 25.08.2011
Сообщений: 140
По умолчанию Потоки и парсинг. Как воплотить

В двух словах. Если ставить критическую секцию то ВСЕ потоки будут ожидать пока завершится один. Если основная идея программы парсинг то потоки скорости не прибавят в таком случае.
Вопрос: как сделать полноценный поток с парсингом?
В идеале я вижу это так: Поток как копия программы, выполняет все действия и ни в чем не ограниченна. Но блин пока у меня скорости не чувствуется)
Зод вне форума Ответить с цитированием
Старый 13.02.2012, 15:53   #2
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,527
По умолчанию

Цитата:
Поток как копия программы, выполняет все действия
все потоки выполняют ОДНИ и те же действия с ОДИНАКОВЫМИ данными?

1.потоки должны работать с разными данными.
2.по возможности эти данные не должны пересекаться. Пересечение данных = критическая секция.
программа — запись алгоритма на языке понятном транслятору
evg_m вне форума Ответить с цитированием
Старый 13.02.2012, 16:27   #3
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

Организуйте хранилищеп отоков на основе TList, или напишите свой пул потоков.
Человек_Борща вне форума Ответить с цитированием
Старый 13.02.2012, 22:16   #4
prey2009
 
Регистрация: 21.05.2011
Сообщений: 8
По умолчанию

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

Код:
type
  TNewThread = class(TThread)
  private
    http: TIdHTTP;
    URL, Response: String;
    procedure ParseData;
  protected
    procedure Execute; override;
  public
    procedure Sync;
  end;

var
  CurIndex: Integer;
  URLList, ParsedData: TStringList;

procedure TNewThread.Sync;
begin
  Form1.StaticText1.Caption := 'Пропарсено: ' + IntToStr(CurIndex) + ' страниц';
end;

procedure TNewThread.ParseData;
begin
  // здесь инструкции парсинга страницы;
  ParsedData.Add('распарсенные данные');
end;

procedure TNewThread.Execute;
begin
   while (not Terminated) do
    begin
      URL := URLList[CurIndex];
      http := TIdHTTP.Create(nil);
      try
       Response := http.Get(URL);
      except
      end;
      ParseData;
      Inc(CurIndex);
      Synchronize(Sync);
      http.Free;
    end;
end;
Про критические секции читал, но правильно применить их не могу (потоки наоборот только еще больше рассинхронизируются). Причина скорее всего в глобальной переменной CurIndex, т.к. она используется всеми потоками одновременно.
prey2009 вне форума Ответить с цитированием
Старый 13.02.2012, 22:30   #5
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

я бы сделал(при такой системе) еще один метод для синхрониз, и именно он будет брать строку из листа и увеличивать индекс.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 14.02.2012, 13:55   #6
prey2009
 
Регистрация: 21.05.2011
Сообщений: 8
По умолчанию

Цитата:
Сообщение от Пепел Феникса
я бы сделал(при такой системе) еще один метод для синхрониз, и именно он будет брать строку из листа и увеличивать индекс.
Спасибо за ответ. Попробовал так:

Код:
procedure TNewThread.Sync2;
begin
  URL := URLList[CurIndex];
  Inc(CurIndex);
end;

procedure TNewThread.Execute;
begin
   while (not Terminated) do
    begin
      Synchronize(Sync2);
      http := TIdHTTP.Create(nil);
      try
       Response := http.Get(URL);
      except
      end;
      Synchronize(Sync);
      ParseData;
      http.Free;
    end;
end;
Теперь ссылки одинаковые не берутся, но данные добавляются не по порядку (один поток опережает другой и добавляет свои данные первым), и отсчет строк сразу начинается с количества потоков (все потоки при создании выполняют синхронизацию и каждый увеличивает индекс)
prey2009 вне форума Ответить с цитированием
Старый 14.02.2012, 15:17   #7
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

они не обязаны завершаться в том порядке в котором начали.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 14.02.2012, 17:58   #8
prey2009
 
Регистрация: 21.05.2011
Сообщений: 8
По умолчанию

Цитата:
Сообщение от Пепел Феникса
они не обязаны завершаться в том порядке в котором начали.
Мне как раз это и нужно И как сделать, чтобы потоки при запуске не увеличивали индекс на их количество?

Последний раз редактировалось prey2009; 14.02.2012 в 18:01.
prey2009 вне форума Ответить с цитированием
Старый 14.02.2012, 19:10   #9
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Цитата:
Мне как раз это и нужно
сделайте грамотную привязку потока, например если в гриде таблица, где первый столбец адрес прокси, а второй это состояние, то номер ячейки/адреса(должен храниться в потоке) будет использован для сообщения информации именно об этом потоке.
или же храните адрес и после парсинга используйте его чтоб дать понять что инфа именно об этом адресе.
а если же нужно строго по порядку, то один поток будет всего.
Цитата:
И как сделать, чтобы потоки при запуске не увеличивали индекс на их количество?
при запуске поток тут же берет себе адрес, логично же что индекс растет?
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 14.02.2012, 22:33   #10
prey2009
 
Регистрация: 21.05.2011
Сообщений: 8
По умолчанию

Пепел Феникса, можете поподробнее о привязке потоков рассказать?А именно, как ее использовать в этом случае

Пока я вижу решение проблемы так: сделать, чтобы потоки ждали друг друга, пока у всех их не закончится получение страницы, а после этого каждый поток по очереди парсит свою страницу и записывает данные. Надеюсь, я в правильном направлении копаю?
prey2009 вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как воплотить идею? Помогите! Mitya1 Свободное общение 25 21.12.2014 14:40
У меня есть идея!(незнаю как воплотить) johnifer PHP 1 24.11.2010 15:14
как воплотить принцип двух экранов Image (Delphi)? FrankyKaup Помощь студентам 1 17.08.2010 22:29
Выделение отцовского пункта выпадающего меню во время прохода по дочерным. Как воплотить? Dim23 HTML и CSS 3 20.03.2010 23:57