Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Как избежать гонок в потоках [D6, WinXP]


Страницы:   1 2 3 4 5

leonidus ©   (2005-05-31 10:38:00) 

Мастера подскажите пожалуйста. Я написал небольшую программу, она скачивает новости с разных сайтов, и затем парсит каждую скачанную страницу на предмет нужной информации. Т.е. программа состоит из бвух блоков - блок закачки (качается сразу в несколько потоков, для каждой страницы с новостями свой поток) и блок парсинга (в нем также предусмотрена многопоточность, при этом для каждой скачанной страницы должен запускаться свой экземпляр одного и тогоже потока). Результаты парсинга (заголовки новостей) помещаются в массив. И вот в чем проблема. Если одновременно скачаются две страницы и одновременно начнут работать два парсера, то может так получиться, что они будут обращаться к одному элементу массив, что бы записать в него полученный заголовок новости. Т.е. я тап понимаю это ситуация гонок. Подскажите как этого избежать. Может есть какие-то статьи по этому поводу, я что-то ничего толком не нашел. Заранее спасибо.


Семен Сорокин   (2005-05-31 15:26:00) [81]


> где грабли?

а вот про это:
synchronize(showresult);
в Execute не забыли?


leonidus   (2005-05-31 15:07:00) [82]

Понятно...в общем делаю так:

type
...
...

  TThread_work = class(TThread)
  private
    { Private declarations }
    st:string;
  protected
    procedure Execute; override;
    procedure showresult;
  public
  end;

var
 FCS:TCriticalSection;
 t:TThread_work;
 a:array[1..10] of string;
 nom:integer;

implementation

{$R *.dfm}

procedure TThread_work.showresult;
var
i:integer;
begin
for i:=1 to nom do
 begin
  form1.memo1.Lines.Add(a[i]);
 end;
  form1.memo1.Lines.Add('---');

end;

procedure TThread_work.Execute;
begin
FCS.Enter;
inc(nom);
a[nom]:=t.st;

FCS.Leave;
synchronize(showresult);
end;

procedure TForm1.Button1Click(Sender: TObject);
//запускаем потоки
begin
FCS:=TCriticalSection.Create;
nom:=0;

t:=TThread_work.Create(true);
t.FreeOnTerminate:=true;
t.st:='поток1';
t.Resume;

t:=TThread_work.Create(true);
t.FreeOnTerminate:=true;
t.st:='поток2';
t.Resume;
end;

в результате получаются не однозначная картина то

поток1
поток2
---

то вообще:
поток1
---

где грабли?


Игорь Шевченко   (2005-05-31 11:27:00) [83]

leonidus ©   (31.05.05 11:08) [2]


> а еще примеры по проще есть


Есть. Например, TThreadList в classes.pas


Anatoly Podgoretsky   (2005-05-31 11:22:00) [84]

Может вместо критических секци даже лучше использовать специализирование средство TMultiReadExclusiveWriteSynchronizer


Digitman   (2005-05-31 11:14:00) [85]


> может так получиться, что они будут обращаться к одному
> элементу массив


синхронизация тебе нужна .. смотри все касаемое критических секций


leonidus   (2005-05-31 11:08:00) [86]

Спасибо Игорь, а еще примеры по проще есть, а то там клиент-сервер и мне сложновато зерна от плевел отделить?


Игорь Шевченко   (2005-05-31 10:56:00) [87]

Использовать синхронизацию, например, защищать обращения к массиву критической секцией. Примеры есть в Program Files/Borland/Delphi/Demos/Midas/Pooler/*.*


Страницы:   1 2 3 4 5

Наверх

Титульная страница Поиск, карта сайта Написать письмо