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

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

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

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

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

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

Есть процедура примерно следующего содержания:
взять строчку из мемо
цикл от 0 до 100
грузим данные в виде: сайт + i(от цикла) + текст из мемо
парсим данные из загруженой страницы.

Хочу сделать 5 потоков через сиджоб. Мне нужно в секцию поставить сам цикл так:
начало секции
взять строчку из мемо
удалить строчку взятую из мемо
конец секции
цикл от 0 до 100
запрос
снова секция для парса.

или как? понимаю что парс все равно в один поток будет а вот как оптимизировать закачку? Если не ограничивать цикл то каждый поток будет грузить 100 раз один и тот же текст а нужен разный.
Зод вне форума Ответить с цитированием
Старый 29.08.2012, 12:16   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
Если не ограничивать цикл то каждый поток будет грузить 100 раз один и тот же текст
Чего это? Если ты организовываешь некий класс потока, в котором есть поле с чем-нить типа idHTTP для загрузки, то соответственно этот поток будет работать только с тем что выдаст этот компонент, принадлежавший потоку.
Соответственно компонент создается в начале потока и освобождается в конце.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 29.08.2012, 14:01   #3
Зод
Форумчанин
 
Регистрация: 25.08.2011
Сообщений: 140
По умолчанию

То есть если я сделаю вот так:
Код:
procedure TForm1.Button1Click(Sender: TObject);
begin
new1 := tnew.create(true);
new1.freeonterminate := true;
new1.priority := tpidle;
new2 := tnew.create(true);
new2.freeonterminate := true;
new2.priority := tptimecritical;
new3 := tnew.create(true);
new3.freeonterminate := true;
new3.priority := tptimecritical;
new4 := tnew.create(true);
new4.freeonterminate := true;
new4.priority := tptimecritical;
new5 := tnew.create(true);
new5.freeonterminate := true;
new5.priority := tptimecritical;
new1.resume;
new2.resume;
new3.resume;
new4.resume;
new5.resume;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
cs.free;
end;

{ tnew }
procedure tnew.execute;
var
i: integer;
HTTP : THTTPSend;
begin
for i := 1 to 10 do
begin
http := THTTPSend.Create;
HTTP.HTTPMethod('GET',Form1.Memo1.Lines[i]);
Form1.Memo1.Lines.Delete(i);
end;
end;
То у меня будет одновременно качаться по 5 строк из Мемо? У меня лично нет. Нужно же синхронизировать все. А как кроме критич. секции это сделать на примере?

Последний раз редактировалось Зод; 29.08.2012 в 14:11.
Зод вне форума Ответить с цитированием
Старый 29.08.2012, 14:36   #4
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,526
По умолчанию

зачеркнутово-первых при старте потока вы получите AV. т.к. используете несозданный объект. но будут утечки памяти нет удаления не нужных более объектов.
во-вторых действия по получению и отметке обработки разнесены во-времени вероятен вариант когда два и более потоков будут качать одну ссылку. (при медленном канале связи)
в-третьих при удалении строк число строк меняется а цикл for свои границы считает неизменными(считает неизменными), значит выход за границу массива (списка).
в-четвертых для нормальной работы поток не должен знать где хранятся ссылки. Он должен уметь спросить "эй а что мне качать" и ему должны уметь ответить.
программа — запись алгоритма на языке понятном транслятору

Последний раз редактировалось evg_m; 29.08.2012 в 14:42.
evg_m вне форума Ответить с цитированием
Старый 29.08.2012, 14:41   #5
eval
Подтвердите свой е-майл
 
Регистрация: 29.08.2012
Сообщений: 4,011
По умолчанию

Цитата:
А как кроме критич. секции это сделать на примере?
А с секциями значит знаете?
eval вне форума Ответить с цитированием
Старый 29.08.2012, 15:13   #6
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,526
По умолчанию

в развитие моего предыдущего поста. примерный план общения потока и основной формы.

Код:
TmyTh =class;
TNotifyThred =procedure(senerThread: TMyTh);

TmyTh =class(TThread)
private // поля и методы для собственой работы
  FcuurrURL: string;
  FOnGetURL, FOnLoadedURL: TNotifyThread;
  procedure GetURL;
  procedure LoadedURL;

public // свойства для общения 
  property OnGetURL: TnotifyThread write FGetURL;
  property OnLoadedURL: TNotifyThread write FLoadedURL; 
  property URL: string read FcurrURL write FcurrURL;
end;

procedure TmyTh.execute;
begin
  while terminated do begin 
    synhronize(self.GetURL); // "спрашиваем" что делать
    if self.FcurrURL='' then Break; //а нам сказали что больше качать нечего
    HTTP.HTTPMethod('GET', self.FcurrURL); 
    syncronize(self.LoadedURL); //"говорим" что закончили данную закачку
  end;
end;

procedure TmyTh.GetURL;
begin
  self.FonGetURL(self); //вызываем известное нам процедуру общения и говорим что это мы (self)
end;

procedure TmyTh.LoadedURL;
begin
  self.FonLoadedURL(self); //вызываем известную нам процедуру общения и говорим что это мы (self)
end;
Код:
Tform1 =class(TForm)
...
private
  procedure doGetURL(sender: TMyTh);
  procedure doLoadedURL(sender: TMyTh);
....
end;

procedure Tform1.....
begin
  th1:=TMyTh.Create;
// объясняем как с нами связаться
  th1.OnGetURL:=self.DoGetURL; // чтобы спросить что качать будет использована указанная процедура 
  th1.OnLoadedURL:=self.DoLoadedURL; // чтобы сказать что закачка выполнена использована указанная процедура
// теперь готовы к запуску
   .....
end;

procedure Tform1.doGetURL(sender: TMyTh); //нас спрашивают что качать и мы знаем кто спрашивает (sender)
begin
  for j:=0 to self.Memo1.Lines.count-1 do begin
    if self.Memo1.Lines.Objects[j]=nil then begin // проверяем не занята ли строка (качает другой поток)
      self.memo1.lines.objects[j]:=sender; //отметили кто качает
      sender.URL:=self.memo1.Lines[j]; // сказали что качать
      break;   
    end;
  end;
end;

procedure Tform1.doLoadedURL(sender: TMyth);  //нам говорят что закачка завершена мы знаем кто это (sender)
begin
  j:=self.memo1.Lines.Indexof(sender.URL);
  if j<0 then // а строки-то и нет
  else if self.memo1.lines.objects[j]=sender then begin // это наша строка
    self.memo1.lines.Delete(j); // теперь уверенно удаляем
  end
  else // это не наша строка
  ;
// наверное так и хочется здесь сразу же сказать что ему делать дальше
// но лучше этого не делать! подождите пусть сам спросит, вдруг у него какие-то другие планы.
end;
программа — запись алгоритма на языке понятном транслятору

Последний раз редактировалось evg_m; 29.08.2012 в 15:20.
evg_m вне форума Ответить с цитированием
Старый 29.08.2012, 16:39   #7
Neobrat
Форумчанин
 
Регистрация: 10.12.2007
Сообщений: 124
По умолчанию

1. лично я создал бы отдельный класс, где держал бы список url.
2. получении и добавление из этого класса защитил бы критической секцией.
3. удалял строчку сразу из списка, после того как отдали строчку потоку.
4. таким образом новому потоку отдавал бы стразу первую строчку.
5. через таймер и WaitForMultipleObjects проверял закончили ли потоки всю обработку.

в вдогонку
6. на событиях и функций ожидания создал бы свои Start,Stop и т.д.
7. Не использовал бы FreeOnTerminate
8. Не использовал бы Synhronize(при малых объемах закачиваем страниц форма будет не доступна пользователю)

хотя.. вариантов как это сделать много)))

p.s. хотя бы запоминай индекс последней забранной потоком строки и при удалении строчки соответственно следи за индексом. как минимум при выделение строчки потоку уйдешь от лишнего цикла.
Русский язык не мой конёк

Последний раз редактировалось Neobrat; 29.08.2012 в 16:43.
Neobrat вне форума Ответить с цитированием
Старый 29.08.2012, 20:46   #8
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

http://programmersforum.ru/showthrea...32#post1087932
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
потоки и цикл While .. do Человек_Борща Общие вопросы Delphi 3 03.06.2011 14:31
Цикл по времени - Как сделать так чтобы цикл выполнялся к примеру 10 секунд ? Anarki Общие вопросы C/C++ 3 13.11.2009 19:23
Цикл с предусловием. ( цикл while) Цикл с постусловием. (цикл repeat ... until) Mr.User Помощь студентам 9 23.11.2007 01:34