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;

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

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


ANB   (2008-04-18 15:49:00) [1]

to Palladin :

Тупейший пример, как передать инфу в основной поток, не используя синхронизацию и критических секций (т.е. без приостановки работы потока).

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
 StdCtrls;

type
 TMyThread = class(TThread)
 protected
   procedure Execute; override;
 public
   EditHandle : THandle;
 end;

 TForm1 = class(TForm)
   btnStart: TButton;
   btnStop: TButton;
   Edit1: TEdit;
   Edit2: TEdit;
   Edit3: TEdit;
   procedure btnStartClick(Sender: TObject);
   procedure btnStopClick(Sender: TObject);
   procedure Edit1KeyPress(Sender: TObject; var Key: Char);
 private
   { Private declarations }
 public
   { Public declarations }
   T1, T2, T3 : TMyThread;
 end;

var
 Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.btnStartClick(Sender: TObject);
begin
 PostMessage(Edit1.Handle, WM_CHAR, 0, 0);
 PostMessage(Edit2.Handle, WM_CHAR, 0, 0);
 PostMessage(Edit3.Handle, WM_CHAR, 0, 0);
 T1 := TMyThread.Create(True);
 T2 := TMyThread.Create(True);
 T3 := TMyThread.Create(True);
 T1.FreeOnTerminate := True;
 T2.FreeOnTerminate := True;
 T3.FreeOnTerminate := True;
 T1.EditHandle := Edit1.Handle;
 T2.EditHandle := Edit2.Handle;
 T3.EditHandle := Edit3.Handle;
 T1.Resume;
 T2.Resume;
 T3.Resume;
end;

{ TMyThread }

procedure TMyThread.Execute;
var i : LongInt;
begin
 for i := 10 to 1000000 do begin
   if Terminated then begin
     PostMessage(EditHandle, WM_CHAR, 1, 0);
     Exit;
   end;
   PostMessage(EditHandle, WM_CHAR, i mod 256, 0);
   Sleep(100);
 end;
end;

procedure TForm1.btnStopClick(Sender: TObject);
begin
 T1.Terminate;
 T2.Terminate;
 T3.Terminate;
end;

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
 with Sender as TEdit do begin
   Text := IntToStr(Byte(Key));
 end;
end;

end.


Palladin   (2008-04-18 11:53:00) [2]


> Я ж тебе процитировал твои слова, где ты играть предлагал.

процитировал одно, а сказал другое, у меня нет ни слова про игры

я ЦУП'у сказал, что пусть домашние задания дает не мне, а детям своим или чужим, будет куда полезней... мне его домашние задания, с какими то методами класса, никуда не уперлись...


> Замнем?

справедливость восстановлена, замнем


> У меня в Source в каталоге indy вообще нет подкаталогов

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


 procedure DoConnectTimeout(ATimeout: Integer);
 var
   LSleepTime: Integer;
   LInfinite: Boolean;
 begin
   if ATimeout = IdTimeoutDefault then begin
     ATimeout := IdTimeoutInfinite;
   end;
   LInfinite := ATimeout = IdTimeoutInfinite;
   with TIdConnectThread.Create(True) do try
     FBinding := Binding;
     Resume;
     // Sleep
     if TIdAntiFreezeBase.ShouldUse then begin
       LSleepTime := Min(GAntiFreeze.IdleTimeOut, 125);
     end else begin
       LSleepTime := 125;
     end;

     if LInfinite then begin
       ATimeout := LSleepTime + 1;
     end;

     while ATimeout > LSleepTime do begin
       IdGlobal.Sleep(LSleepTime);
       ATimeout := ATimeout - LSleepTime;

       if LInfinite then begin
         ATimeout := LSleepTime + 1;
       end;

       TIdAntiFreezeBase.DoProcess;
       if Terminated then begin
         ATimeout := 0;
         Break;
       end;
     end;
     IdGlobal.Sleep(ATimeout);
     //
     if Terminated then begin
       if FExceptionMessage <> '' then begin
         if FLastSocketError <> 0 then begin
           raise EIdSocketError.CreateError(FLastSocketError, FExceptionMessage);
         end;
         EIdConnectException.Toss(FExceptionMessage);
       end;
     end else begin
       Terminate;
       Close;
       WaitFor;
       EIdConnectTimeout.Toss(RSConnectTimeout);
     end;
   finally Free; end;
 end;

procedure TIdConnectThread.Execute;
begin
 try
   try
     FBinding.Connect;
   except
     on E: EIdSocketError do begin
       if (E.LastError <> Id_WSAEBADF) and (E.LastError <> Id_WSAENOTSOCK) then begin
         raise;
       end;
     end;
   end;
 except
   on E: Exception do begin
     FExceptionMessage := E.Message;
     if E is EIdSocketError then begin
       FLastSocketError := EIdSocketError(E).LastError;
     end;
   end;
 end;
 // Necessary as caller checks this
 Terminate;
end;


то есть, все банально, подключение в другом потоке...


Оригинал   (2008-04-18 11:39:00) [3]


> Palladin ©   (18.04.08 11:16) [142]
>
> > Оригинал   (18.04.08 11:05) [140]
>
>
>
> > Обороты сбавь. Хорошо? играй с детьми своими, если они
> у
> > тебя есть.
>
> я чем то тебя оскорбил? тебе что то не нравится? вроде как
> бы не тебе адресовалось. играть с детьми я никому не предлагал,
>  а вот мне тут какое то вдруг домашнее задание давать начали.
>  так может быть обороты то не мне сбавить? а тебе вкурить
> ситуацию. и на личности переходить не будем.


Я ж тебе процитировал твои слова, где ты играть предлагал.
Ну да ладно. Замнем? Зачем разводить здесь ерунду.

У меня в Source в каталоге indy вообще нет подкаталогов. -(


Palladin   (2008-04-18 11:17:00) [4]


> Оригинал   (18.04.08 11:12) [141]

должен быть. %INDY%\Source\Core\IdIOHandlerStack.pas


Palladin   (2008-04-18 11:16:00) [5]


> Оригинал   (18.04.08 11:05) [140]



> Обороты сбавь. Хорошо? играй с детьми своими, если они у
> тебя есть.

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

по поводу, кода: серьезных претензий нет. теперь много народу прочитает и узнает как прервать get в indy.


Оригинал   (2008-04-18 11:12:00) [6]


> Palladin ©   (18.04.08 10:28) [138]
>
> > Оригинал   (18.04.08 01:15) [135]
>
> IdIOHandlerStack.pas


Нет у меня такого файла-(
(BDS, indy10)


Оригинал   (2008-04-18 11:05:00) [7]


> Palladin ©   (18.04.08 10:01) [136]
>
> > ЦУП ©   (17.04.08 21:59) [133]
>
> это ты ребенку своему домашние задания будешь давать


I>
> Palladin ©   (17.04.08 19:51) [127]
> >Оригинал (17.04.08 19:44) [126]
>
>
> а теперь поиграем в 10 отличий исключения в следствии закрытия
> сокета вручную и другого возникшего из-за реального закрытия
> в следствие системной ошибки...


Обороты сбавь. Хорошо? играй с детьми своими, если они у тебя есть.

Теперь по твоему вопросу как отличить исключение искусственное от любого другого в приведенном примере.
Задачка-то ведь совсем простая. Для этого буквы писать надо?

1. В приведенном поточном классе добавляем метод, например Break
2. Добавляем boolean-флаг в private-секцию, изначально = False.
3. Вместо внешнего обращения к IdHTTP обращаемся к методу, который выставляет флаг и закрывает сокет.
4. При возникновении исключения проверяем флаг.
5. Всё.

Код с минимальными изменениями:

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls, ExtCtrls, IdBaseComponent,
 IdComponent, IdTCPConnection, IdTCPClient, IdHTTP ;

type

 TIH=class(TThread)
 private
   FURL: String;
   FH: TIdHTTP;
   FIsBreak: Boolean;
 protected
   procedure Execute; override;
 public
   constructor Create(URL: String);
   procedure Break;
 end;

 TForm1 = class(TForm)
   Button1: TButton;
   Timer1: TTimer;
   procedure Timer1Timer(Sender: TObject);
   procedure Button1Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;
 H: TIH;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
 H := TIH.Create(' http://10.74.1.35/hp/device/this.LCDispatcher?nav=hp.Usage');
 Timer1.Enabled := True;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
 H.Break;
 Timer1.Enabled := False;
end;

{ TIH }

procedure TIH.Break;
begin
 if Assigned(FH) then
 begin
   FIsBreak := True;
   FH.Socket.Close;
 end;
end;

constructor TIH.Create(URL: String);
begin
 inherited Create(True);
 FUrl := URL;
 FreeOnTerminate := True;
 FIsBreak := False;
 Resume;
end;

procedure TIH.Execute;
var
 s: String;
begin
 FH := TIdHTTP.Create(nil);
 try
   try
     FH.Get(FURL);
   except
     ON E: Exception do
     begin
       if FIsBreak then s := ' Break connection' else s :='';
       MessageBox(0,PChar(E.Message+s),PChar(E.Message),MB_OK);
     end;
   end;
 finally
   FH.Free;
 end;
end;

end.


Palladin   (2008-04-18 10:50:00) [8]


> Я бы постарался вообще не использовать HTTP в качестве транспорта.

чем http отличается от не http в плане соединения/отправки/получения/разъединения?


> Во всяком случае использование Синхронизе для передачи информации
> о ходе выполнения в основной поток вместо посылки сообщения
> - это не меньшая запущенность.

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

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


Palladin   (2008-04-18 10:28:00) [9]


> Оригинал   (18.04.08 01:15) [135]

IdIOHandlerStack.pas


ANB   (2008-04-18 10:20:00) [10]


> >ANB(17.04.08 19:16) [124]
>
> предлагаешь использовать TWebBrowser в качестве транспорта.
> .. как все запущено...

Я бы постарался вообще не использовать HTTP в качестве транспорта.

Во всяком случае использование Синхронизе для передачи информации о ходе выполнения в основной поток вместо посылки сообщения - это не меньшая запущенность.

ИМХА :
Потоки надо начинать использовать только если все прочие методы ускорения процесса уже использованы. Далее, перед их использованием неплохо было бы оценить - а действительно ли это даст ускорение, не забывая, что количество процессоров на рабочей станции невелико.
Если  все же принято решение о распараллеливании, то необходимо качественно изучить эту тему и все грабли с ней связанные. А грабли не только в правильном и неправильном использовании Синхронизе.

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


Palladin   (2008-04-18 10:01:00) [11]


> ЦУП ©   (17.04.08 21:59) [133]

это ты ребенку своему домашние задания будешь давать

давай, помогай по полной. в каком классе? какой метод? зачем он там нужен? я автору уже помог, теперь, раз ты вызвался, до конца завершай начатое...


Оригинал   (2008-04-18 01:15:00) [12]


> MetalFan ©   (18.04.08 00:36) [134]
> > Оригинал   (17.04.08 19:44) [126]зря время на написание
> примера тратили.можно посмотреть реализацию обработки TIdHttp.
> ConnectionTimeoutтам как раз нечто подобное и сделано.


Если ты мне скажешь конкретное название файла, в котором находится реализация - я посмотрю. Ок?


MetalFan   (2008-04-18 00:36:00) [13]


> Оригинал   (17.04.08 19:44) [126]

зря время на написание примера тратили.
можно посмотреть реализацию обработки TIdHttp.ConnectionTimeout
там как раз нечто подобное и сделано.


ЦУП   (2008-04-17 21:59:00) [14]


> Palladin ©   (17.04.08 19:51) [127]
>Оригинал (17.
> 04.08 19:44) [126]а теперь поиграем в 10 отличий исключения
> в следствии закрытия сокета вручную и другого возникшего
> из-за реального закрытия в следствие системной ошибки...
>


А теперь в качестве домашнего задания подумаем и решим, как это сделать. Маленькая подсказка - создаём в классе метод и...


Anatoly Podgoretsky   (2008-04-17 21:25:00) [15]

> Palladin  (17.04.2008 21:01:10)  [130]

И вообще почему ты решил, что я сплю?


Anatoly Podgoretsky   (2008-04-17 21:24:00) [16]

> Palladin  (17.04.2008 21:01:10)  [130]

Это что уже заметно?


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

интересно, а Анатоль знает, что он во сне разговаривает, а его мощнейший разум  проецирует поток сознания прямо на форум... :)


Anatoly Podgoretsky   (2008-04-17 20:32:00) [18]

> Palladin  (17.04.2008 19:51:07)  [127]

А я посмотрю как это удастся, без внешнего воздействия.


Anatoly Podgoretsky   (2008-04-17 20:30:00) [19]

> Palladin  (17.04.2008 19:05:01)  [121]

Хе, хе - это исключение, и мне кажется мы говорим о правилах хорошего тона, а не следованию им.
Исключения должны быть осознаными, а правила в данном случае вторичными, поскольку наверх всплывают другие соображения.


Palladin   (2008-04-17 19:51:00) [20]


>ANB(17.04.08 19:16) [124]

предлагаешь использовать TWebBrowser в качестве транспорта... как все запущено...


>Оригинал (17.04.08 19:44) [126]


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


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

Наверх

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