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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 07.03.2012, 20:01   #11
trafbite
Форумчанин
 
Регистрация: 21.07.2007
Сообщений: 103
По умолчанию

эмммм... Так я не понимать можно простенький примерчик? Буду ну очень признателен!
trafbite вне форума Ответить с цитированием
Старый 11.03.2012, 09:40   #12
trafbite
Форумчанин
 
Регистрация: 21.07.2007
Сообщений: 103
По умолчанию

И все таки, не смог я самостоятельно разобраться, выручайте

Вот создаю потоки:

Код:
procedure TForm1.Button2Click(Sender: TObject);
var
  mythread:tthread;
  i:integer;
begin
  for i:=1 to strtoint(edit3.Text) do mythread:=thr.Create (false);
end;

(Для теста в Edit3.Text число 10).

Вот сам поток:

Код:
unit Unit2;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ComCtrls, HttpSend, synautil;

type
  thr = class(TThread)
  private
    phrase:string;
    List: Tstringlist;

  protected
    procedure load;
    procedure upload;
    procedure Execute; override;
  end;

implementation

uses unit1;

  var
    Count: integer =-1;
    CS: TRTLCriticalSection;
    Nofollow, Dofollow: TStringList;


procedure thr.load;
begin
  phrase:=form1.Edit1.Text;
  list:=tstringlist.Create;
  List.LoadFromFile(Form1.Edit2.Text);
end;

procedure thr.upload;
begin
  Form1.Memo1.Text:=Dofollow.Text;
  Form1.Memo2.Text:=Nofollow.Text;
end;

procedure thr.Execute;
var
  http: THttpSend;
  templist:tstringlist;
  i: integer;
begin
  FreeOnTerminate:=true;
  InitializeCriticalSection(CS);

  Nofollow:=TstringList.Create;
  Dofollow:=TstringList.Create;

  templist:=tstringlist.Create;

  synchronize(load);

  
  EnterCriticalSection(CS);
    if Count<List.Count-1 then inc(Count);
  LeaveCriticalSection(CS);

  
  http := THTTPSend.Create;
  http.Protocol := '1.1';
  try
    http.Clear;
    http.HTTPMethod('GET', List[Count]);
    templist.Clear;
    templist.Text:=ReadStrFromStream(http.Document, http.Document.Size);  
  finally
    http.Free;
  end;

  
  for i:=0 to templist.Count-1 do begin
    if (pos(phrase,templist[i])>0) then begin
        if pos('ofollow',templist[i])>0 then
          Nofollow.Add(List[Count])
        else
          Dofollow.Add(List[Count]);
    end;
  end;


  synchronize(upload);

  
DeleteCriticalSection(CS);

list.Free;
templist.Free;
NoFollow.Free;
Dofollow.Free;
end;

end.
Не работает. Точнее работает, но неведомым мне способом:

При нажатии на кнопку Button2 уходит 10 GET-запросов - тут все хорошо. Но потом в Memo1 добавляется только одна строка из исходного списка, которая в исходном списке 10 (десятая). С синхронизацией вроде бы все в порядке.

Где накосячил?
trafbite вне форума Ответить с цитированием
Старый 11.03.2012, 10:18   #13
Slym
Участник клуба
 
Регистрация: 07.12.2011
Сообщений: 1,025
По умолчанию

секция одна!!! одна!!! должна быть
а ты их в каждом потоке наплодил да еще через глобальную переменную как оно вапще работает?
Не стесняемся, плюсуем!
Slym вне форума Ответить с цитированием
Старый 11.03.2012, 10:36   #14
Slym
Участник клуба
 
Регистрация: 07.12.2011
Сообщений: 1,025
По умолчанию

накидал за 15 мин так что не судите строго
ПРАВКА 1: из потока вполне безопасно читать из неизменяемого lines мема

Код:
type
  TSyncStrings=class
  private
    FStrings:TStrings;
    Position:integer;
    CS: TRTLCriticalSection;
  public
    constructor Create(Strings:TStrings);
    destructor Destroy;override;
    function NextString(out str:string):boolean;
  end;

type
  thr = class(TThread)
  private
    FSyncStrings:TSyncStrings;
  protected
    procedure Execute; override;
  public
    constructor Create(SyncStrings:TSyncStrings;CreateSuspended: Boolean);reintroduce;
  end;

var
  SyncStrings:TSyncStrings;


{ TSyncStrings }

constructor TSyncStrings.Create(Strings: TStrings);
begin
  inherited Create;
  InitializeCriticalSection(CS);
  FStrings:=Strings;
  Position:=0;
end;

destructor TSyncStrings.Destroy;
begin
  DeleteCriticalSection(CS);
  inherited;
end;

function TSyncStrings.NextString(out str: string): boolean;
begin
  EnterCriticalSection(CS);
  result:=Position<FStrings.Count;
  if result then
  begin
    str:=FStrings[Position];
    inc(Position);
  end;
  LeaveCriticalSection(CS);
end;

{ thr }

constructor thr.Create(SyncStrings: TSyncStrings;
  CreateSuspended: Boolean);
begin
  FSyncStrings:=SyncStrings;
  FreeOnTerminate:=true;
  inherited Create(CreateSuspended);
end;

procedure thr.Execute;
var s:string;
begin
  while not Terminated do
  begin
    if not FSyncStrings.NextString(s) then break;

    sleep(1000);
    //ðàáîòàåì ñ s
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var i:integer;
begin
  if not assigned(SyncStrings) then
    SyncStrings:=TSyncStrings.Create(Memo1.Lines);

  for i:=0 to 10 do
    thr.Create(SyncStrings,false);
end;
Не стесняемся, плюсуем!

Последний раз редактировалось Slym; 11.03.2012 в 10:38.
Slym вне форума Ответить с цитированием
Старый 11.03.2012, 10:45   #15
trafbite
Форумчанин
 
Регистрация: 21.07.2007
Сообщений: 103
По умолчанию

Ого! Спасибо, но пока я тут многого не понимаю - ушел изучать...
trafbite вне форума Ответить с цитированием
Старый 11.03.2012, 13:44   #16
trafbite
Форумчанин
 
Регистрация: 21.07.2007
Сообщений: 103
По умолчанию

Не, прошу прощения, но не могу разобраться с твоим кодом

Вот, например:
Цитата:
type
TSyncStrings=class
Класс то класс, а какой?
Сначала подумал, что это форму так обозвал, а потом выплыло вот это:
Цитата:
procedure TForm1.Button1Click(Sender: TObject);
var i:integer;
И вообще какой-то странный код, он точно на делфи?
trafbite вне форума Ответить с цитированием
Старый 11.03.2012, 13:54   #17
trafbite
Форумчанин
 
Регистрация: 21.07.2007
Сообщений: 103
По умолчанию

Вообще у меня поток в отдельном юните.
Поэтому решил инициализировать крит. секцию при создании формы, а удалить при закрытии, вот так
Создал:
Код:
procedure TForm1.FormCreate(Sender: TObject);
begin
  InitializeCriticalSection(CS); //инициализировали критическую секцию
end;
Удалил:
Код:
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  DeleteCriticalSection(CS); //закрыли ее
end;
Описал ее здесь (а где еще?):
Код:
[...]
type
  TForm1 = class(TForm)
  [...]
  private

  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  CS: TRTLCriticalSection;

implementation

{$R *.dfm}
[...]
Сама процедура потока:
Код:
procedure thr.Execute;
var
  http: THttpSend;
  templist:tstringlist;
  i: integer;
begin
  FreeOnTerminate:=true;

  List:=tstringlist.Create;
  synchronize(load);

  while count<list.Count-1 do begin //делаем цикл, что бы потоки прошли все ссылки из List-а
  
    EnterCriticalSection(CS); //зашли в крит. секцию
      inc(Count);             //увеличили счетчик (что-то тут не то!!!)
    LeaveCriticalSection(CS); //вышли из крит. секции

    http := THTTPSend.Create;
    http.Protocol := '1.1';
    TempList:=tstringlist.Create;
    try
      http.Clear;
      http.HTTPMethod('GET', List[Count]);
      templist.Clear;
      templist.Add(ReadStrFromStream(http.Document, http.Document.Size));
      templist.SaveToFile(ExtractFilePath(Application.ExeName)+inttostr(Count)+'.txt'); //пробую сохранить, что бы проверить работоспособность каждого потока !!!!!
    finally
      http.Free;
      Templist.Free;
    end;

    for i:=0 to templist.Count-1 do begin
      if (pos(phrase,templist[i])<>0) then begin
        form1.Memo1.Lines.Add(List[Count]); //
        break;
      end else begin
        form1.Memo2.Lines.Add(List[Count]); //
        break;
      end;
    end;

    sleep(1000);
  end;

list.Free;
templist.Free;

end;
Так вот при выполнении программы сохраняются файлы НЕ по порядку. Т.е. нумерация может начаться с 5-го, потом 7-й, потом еще какой-нибудь.

Возможно просто некоторые из ссылок не так быстро открываются как другие. Как можно время жизни потока задать?
trafbite вне форума Ответить с цитированием
Старый 11.03.2012, 21:55   #18
phomm
personality
Старожил
 
Аватар для phomm
 
Регистрация: 28.04.2009
Сообщений: 2,899
По умолчанию

Проектик кинь поиграться (коли не жалко, конечно), интересно стало ))
phomm вне форума Ответить с цитированием
Старый 12.03.2012, 01:45   #19
xrob
Форумчанин
 
Регистрация: 18.10.2010
Сообщений: 419
По умолчанию

а можно дурацкий вопрос?
вы вот тут про потоки говорите... про МНОГО потоков, как я понял... да?
т.е. больше 2, больше 4...
я телевизор не смотрю и может что-то пропустил,
но последнее что я знаю про процессоры - это четырех-ядерные...
тогда 4 потока, по одному на ядро и прога работает в 4 раза быстрее.
не если ядро одно... ты хоть милион создай - быстрее работать не будет.
зачем столько потоков?

кстати, чем синхронизация хуже критической секции?
xrob вне форума Ответить с цитированием
Старый 12.03.2012, 08:46   #20
trafbite
Форумчанин
 
Регистрация: 21.07.2007
Сообщений: 103
По умолчанию

Цитата:
Сообщение от phomm Посмотреть сообщение
Проектик кинь поиграться (коли не жалко, конечно), интересно стало ))
Задачу уже решил
Цитата:
а можно дурацкий вопрос?
вы вот тут про потоки говорите... про МНОГО потоков, как я понял... да?
т.е. больше 2, больше 4...
я телевизор не смотрю и может что-то пропустил,
но последнее что я знаю про процессоры - это четырех-ядерные...
тогда 4 потока, по одному на ядро и прога работает в 4 раза быстрее.
не если ядро одно... ты хоть милион создай - быстрее работать не будет.
зачем столько потоков?

кстати, чем синхронизация хуже критической секции?
Ну, как минимум, есть уже 6 ядерные.
Когда какие-то операции, требующие больших вычислительных ресурсов компа выполняются в основном потоке - графическая оболочка программы виснет - для меня не есть гуд.
Если, опять же, в отдельных потоках выполняются операции, требующие больших вычислительных ресурсов компа, то да, возможно максимальное количество потоков, способное увеличить скорость выполняется = количеству ядер. Однако, в моем случае вычислительных возможностей не нужно абсолютно, а вот скорость скачивания страничек, например, при 50 потоках НАМНОГО выше, чем при одном
trafbite вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Многократный запуск одного макроса для обработки информации по нескольким заказам поочередно Ribun Microsoft Office Access 1 30.06.2011 09:36
Копировать строку фильтрованного списка в другую книгу, на последнюю пустую строку Gvaridos Microsoft Office Excel 11 24.11.2010 00:48
Как скопировать строку из одного Stringgrida в другой? Pinkygirl Общие вопросы Delphi 1 16.01.2010 23:25
Списка. Стеки, очереди, Кольца c++ megavolt91 Помощь студентам 0 01.06.2009 20:23
как раскидать сгруппированные данные из одного стобца по нескольким hudoi Microsoft Office Excel 2 07.02.2007 23:42