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

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

потоки


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

Аврам ©   (2008-04-15 21:43:00) 

на форме валяется грид, заполненные данными.
строчек ~20-25 не больше.
по началу написал процедуру которая брала по очереди данные из каждой строчки и анализировала их. потом пришло в голову сделать все это дело через потоки, т.е. загружать например 10 потоков обрабатывать данные, потом по мере анализ освободившиеся потоки начинали обрабатывать следующие данные из грида, пока не проанализируются все.
можно ли так делать? если нет то почему? и как делать грамотней в этом случае?
решение о использовании потоков появилось когда попробовал запустить потоки по сразу всем данным типо того:
for i:=0 to grid.rowount -1 do
begin
     gg := txz.create;
   try
     with gg do
     begin
       Inc(FThreadRefCount);
       Resume;
     end;
   except on EConvertError do
     begin
       gg.Free;
       ShowMessage('That is not a valid number!');
     end;
   end;
end;
end;

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

Жду ответов и советов, спасибо!


Аврам   (2008-04-16 20:57:00) [81]

спасибо, договорились ))


Palladin   (2008-04-16 20:45:00) [82]

звиняй, лекция будет уже только завтра... но будет


Аврам   (2008-04-16 20:42:00) [83]

Palladin, разбираюсь в коде, который ты мне дал, хочу понять что к чему.
Не все понятно, поэтому я постараюсь описать то что ты мне дал, а ты меня поправишь если что не так :)))

Поток TMonitorThread - это поток, который будет следить за потоками.
TWorkThread - поток, который берет данные из грида и обрабатывает их.

сначала я должен создать поток TMonitorThread и дать ему на съедение stringgrid:
var
 new:TMonitorThread;
begin
 new := TMonitorThread.Create(StringGrid1);
 try
    with new do
    begin
      Resume;
    end;
  except on EConvertError do
    begin
      new.Free;
      ShowMessage('That is not a valid number!');
    end;
  end;


дальше я должен создать потоки TWorkThread.
pot :=TWorkThread.Create(StringGrid1.Cols[0]);
  try
    with pot do
    begin
      Resume;
    end;
  except on EConvertError do
    begin
      pot.Free;
      ShowMessage('That is not a valid number!');
    end;
  end;

//ChegoNibudDelaemS(TWorkThread(theListOfThreads[i]).Data); закоментировал так как пока не знаю что здесь будет.

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


Palladin   (2008-04-16 20:29:00) [84]


>sniknik©(16.04.08 20:08) [61]

не все так безсмысленно, аффтар упомянул о получении данных по http, а это уже совсем другой разговор...


Аврам   (2008-04-16 20:25:00) [85]

sniknik, не тебе судить что лучше, если хочешь помочь, то помагай - буду благодарен, а говорить о том чего не знаешь - не стоит. Думаю ты меня понял. Чтобы подобные советы "нанять программиста" и нафига доп. комп. тут больше не обсуждались разъесню немного. Данные будут считыватья в течении 5-8 часов, и нужно постоянно наблюдать за происходящим. (получение результатов). Нашелся никем не используемый компьютер. вот его под это дело и дали. К этйо теме кол-во ком. и его мощность никак не относиться.
Спасибо всем за ответы и за советы.
Учусь. С уважением, А.


sniknik   (2008-04-16 20:08:00) [86]

афигеть... дополнительный компьютер под задачу которая считает данные в stringgrid-е, и тормозит изза потоков... лучше бы программиста наняли.


Palladin   (2008-04-16 19:54:00) [87]


> Аврам   (16.04.08 19:53) [59]

куда хочешь туда и вставляй...


Аврам   (2008-04-16 19:53:00) [88]

Palladin, код который ты привел нужно вставлять в основном приложении или в отдельно созданном уните - потоке ?


Palladin   (2008-04-16 19:30:00) [89]


> вроде бы нигде не ошибся...

все таки ошибся... пропустил Inc(i) в Function _WaitForThreads:Boolean;


Аврам   (2008-04-16 19:27:00) [90]

вах...спасибо! щас буду разбираться...))


Palladin   (2008-04-16 18:38:00) [91]

Type
TWorkThread=Class(TThread)
 Private
  m_theEndFlagP:TMultiReadExclusiveWriteSynchronizer;
  m_bEndFlag:Boolean;
  m_pData:Pointer;
  m_theData:TStringList;

  Function lcGetEndFlag:Boolean;
 Protected
  Procedure Execute; Override;
 Public
  Constructor Create(Const p_theData:TStrings);
  Destructor Destroy; Override;

  Property EndFlag:Boolean Read lcGetEndFlag;
  Property Data:Pointer Read m_pData;
End;

TMonitorThread=Class(TThread)
 Private
  m_theStringGrid:TStringGrid;
  m_nDropLinesTo:Integer;
  Procedure DropLines;
 Protected
  Procedure Execute; Override;
 Public
  Constructor Create(p_theStringGrid:TStringGrid);
End;

Constructor TWorkThread.Create;
Begin
m_theEndFlagP:=TMultiReadExclusiveWriteSynchronizer.Create;
m_theData:=TStringList.Create;
m_theData.AddStrings(p_theData);
m_bEndFlag:=False;
Inherited Create(False);
End;

Destructor TWorkThread.Destroy;
Begin
Inherited;
m_theData.Free;
m_theEndFlagP.Free;
End;

Procedure TWorkThread.Execute;
Var
i:Integer;
Begin
// берем ресурсы
Try
 For i:=0 to Random(10*1000)-1 Do
  Begin
   Sleep(100); // создаем видимость работы в поте интерфейса
   If Terminated Then Exit;
  End;

 m_theEndFlagP.BeginWrite;
 Try
  m_bEndFlag:=True;
 Finally
  m_theEndFlagP.EndWrite;
 End;
Finally
 // освобождаем ресурсы
End;
End;

Function TWorkThread.lcGetEndFlag;
Begin
m_theEndFlagP.BeginRead;
Try
 Result:=m_bEndFlag;
Finally
 m_theEndFlagP.EndRead;
End;
End;

Const
CONST_NOMER_OF_COLUMN_WITH_P=1;

Procedure TMonitorThread.Execute;
Var
theListOfThreads:TList;

Procedure _FreeThreadsList;
Var
 i:Integer;
Begin
 For i:=0 to theListOfThreads.Count-1 Do TThread(theListOfThreads).Free;
 theListOfThreads.Clear;
End;

Function _CreateThreads:Boolean;
Var
 n,P:Integer;
Begin
 Result:=m_theStringGrid.RowCount<>0;
 If Not Result Then Exit;
 n:=0;
 P:=StrToInt(m_theStringGrid.Cells[CONST_NOMER_OF_COLUMN_WITH_P,n]);
 While True Do
  Begin
   Result:=Not Terminated;
   If Not Result Then Exit;
   theListOfThreads.Add(TWorkThread.Create(m_theStringGrid.Rows[n])); Inc(n);
   If (n=m_theStringGrid.RowCount) Then Begin m_nDropLinesTo:=n-1; Exit; End Else
   If StrToInt(m_theStringGrid.Cells[CONST_NOMER_OF_COLUMN_WITH_P,n])<>P Then Begin m_nDropLinesTo:=n-1; Exit; End;
  End;
End;

Function _WaitForThreads:Boolean;
Var
 i:Integer;
Begin
 i:=0;
 While True Do
  Begin
   Result:=Terminated;
   If Result Then Exit;
   If TWorkThread(theListOfThreads[i]).EndFlag Then
    Begin
     ChegoNibudDelaemS(TWorkThread(theListOfThreads[i]).Data);
     Exit;
    End;
   If i=theListOfThreads.Count Then i:=0;
   Sleep(100);
  End;
End;

Begin
theListOfThreads:=TList.Create;
Try
 While True Do
  Begin
   If Terminated Then Exit;
   m_nDropLinesTo:=-1;
   If Not _CreateThreads Then Exit;
   If _WaitForThreads Then Exit;
   Synchronize(DropLines);
   _FreeThreadsList;
  End;
Finally
 _FreeThreadsList;
 theListOfThreads.Free;
End;
End;

Constructor TMonitorThread.Create;
Begin
m_theStringGrid:=p_theStringGrid;
Inherited Create(False);
End;

Procedure TMonitorThread.DropLines;
Var
j,i:Integer;
Begin
If m_nDropLinesTo=-1 Then Exit;
For i:=m_nDropLinesTo to m_theStringGrid.RowCount-1 Do
 For j:=0 to m_theStringGrid.ColCount-1 Do
  With m_theStringGrid Do Cells[j,i-m_nDropLinesTo]:=Cells[j,i];
With m_theStringGrid Do RowCount:=RowCount-m_nDropLinesTo;
End;


сюда еще нужно будет прикрутить оповещение монитора об уничтожении источника данных, TStringGrid'а

вроде бы нигде не ошибся...


Dennis I. Komarov   (2008-04-16 17:38:00) [92]

> [51] Аврам   (16.04.08 17:26)

50 постов спустя появляются все новые и новые исходные :(


Palladin   (2008-04-16 17:37:00) [93]


> Аврам   (16.04.08 17:35) [53]

есть, но это аварийный выход, в случае если по хорошему поток завершатся не хочет, и это чревато неприятностями. от банальной утечки памяти, до блокирования некоторых системных ресурсов...

хорошо раз готов, жди...


Аврам   (2008-04-16 17:35:00) [94]

готов.
я предпологал что есть возможность послать группе потоков принудительный выход, ьез использования If Terminated Then Exit;


Palladin   (2008-04-16 17:33:00) [95]


> Аврам   (16.04.08 17:26) [51]

я не прошу тебя выкладывать тексты... раз ты определить распределение тяжести по алгоритму не в состоянии, то придется в нем на каждый чих с данными (практически через каждую строчку) вставлять следующее
If Terminated Then Exit; , а так же окаймить метод execute скобками try finally end, для корректного освобождения взятых в процессе ресурсов при exit

ты готов к этому?


Аврам   (2008-04-16 17:26:00) [96]

к сожалению я не все исходные тексты могу выкладывать.


Аврам   (2008-04-16 17:25:00) [97]

забыл сказать еще одну важную весчь,в одном месте еще есть загрузка некоторых данных с интернета (есть сервер с данными, которые постоянно меняются).
это выглядит так page := get(***);в page загружается страница и беруться оттуда некоторые данные парсингом.


Dennis I. Komarov   (2008-04-16 17:22:00) [98]

> [48] Palladin ©   (16.04.08 17:21)

Партизаны не сдаются!!!


Palladin   (2008-04-16 17:21:00) [99]

я просто хочу выяснить, на сколько тяжел весь алгоритм в целом и есть ли в нем контрастно тяжеленные места?


Palladin   (2008-04-16 17:16:00) [100]


> Аврам   (16.04.08 17:14) [46]

циклы for to do, while do, repeat until используются в вычислениях или одна только формула?


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

Наверх

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