Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.07.16;
Скачать: CL | DM;

Вниз

Поток в созаднном мной классе   Найти похожие ветки 

 
NORDmen ©   (2006-06-28 21:16) [0]

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

возникают траблы с потоками. т.к. например:
1 стандартный поток delphi - для него нужен свой класс. отсюда возникают траблы. как бы сделать все в одном классе без геморра? ))
2 создание потока срествами winapi - CreateThread(...) но тут тоже трабла :) - нельзя передать указатель на процедуру этого класса, выдает ошибку типа надо это не переменная. можно создать просто процедуру (не принадлежещую к этому классу), но тогда проблемы в том, что эта процедура не видит переменных класса.

как мне сделать сабж?


 
Пусик ©   (2006-06-28 21:24) [1]


> как мне сделать сабж?


Посмотри, как реализован в VCL класс TThread. Сразу все понятно будет.


 
NORDmen ©   (2006-06-28 21:45) [2]

Пусик, огромный респект )))


> Сразу все понятно будет.


мне вот что непонятно - там вызывается
 FHandle := BeginThread(nil, 0, @ThreadProc, Pointer(Self), CREATE_SUSPENDED, FThreadID);

ThreadProc - function ThreadProc(Thread: TThread): Integer;
так вот, как этой ф-ии ThreadProc передается параметр, если она передается в beginthread по указателю?

т.е. как в ThreadProc правильно передаются параметры?


 
Пусик ©   (2006-06-28 22:07) [3]


> NORDmen ©   (28.06.06 21:45) [2]


FHandle := BeginThread(nil, 0, @ThreadProc, Pointer(Self), CREATE_SUSPENDED, FThreadID);
Self - в данном случае указатель на экземпляр твоего класса.
ThreadProc получает его параметром, затем(после приведения) в поточной функции можно использовать методы и поля твоего класса.

function ThrProc(p: Pointer): Integer;
begin
  TMyClass(p).Field1 := ...
end;


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


 
Leonid Troyanovsky ©   (2006-06-29 00:12) [4]


> NORDmen ©   (28.06.06 21:16)  

> 1 стандартный поток delphi - для него нужен свой класс.
> отсюда возникают траблы. как бы сделать все в одном классе
> без геморра? ))


Пардон, а в чем, собс-но, оный геморр?
В создании, использовании другого класса?

Ярых поборников ООП - прошу отреагировать.

--
Regards, LVT.


 
Fay ©   (2006-06-29 00:14) [5]

2 Leonid Troyanovsky ©   (29.06.06 0:12) [4]
> Ярых поборников ООП - прошу отреагировать
Ничего не скажу. Не использую TThread-идов.


 
Джо ©   (2006-06-29 00:24) [6]

> [5] Fay ©   (29.06.06 00:14)
> 2 Leonid Troyanovsky ©   (29.06.06 0:12) [4]
> > Ярых поборников ООП - прошу отреагировать
> Ничего не скажу. Не использую TThread-идов.

Я, хоть и не "ярый поклонник", но изпользую TTread"ы и считаю их чертовски удобными :-)


 
Пусик ©   (2006-06-29 00:57) [7]


> Leonid Troyanovsky ©   (29.06.06 00:12) [4]


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

ООП так ООП.

Вот пример:

unit Unit1;

interface

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

type

 TPusikSample=class;

 TPusikThread=class(TThread)
 private
   FPusikSample: TPusikSample;
 protected
   procedure Execute; override;
 public
   constructor Create(aParent:TPusikSample);
 end;

 TPusikSample=class
 private
   FCS: TCriticalSection;
   FField1: String;
   FField2: String;
   FField3: String;
   FField4: String;
   FThread: TPusikThread;
   procedure Lock;
   procedure Unlock;
   procedure SetField1(const Value: String);
   procedure SetField2(const Value: String);
   procedure SetField3(const Value: String);
   procedure SetField4(const Value: String);
   function GetField1: String;
   function GetField2: String;
   function GetField3: String;
   function GetField4: String;
 public
   constructor Create;
   destructor Destroy; override;

   procedure StartThread;
   procedure OnTerminateThread(Sender: TObject);

   property Field1: String read GetField1 write SetField1;
   property Field2: String read GetField2 write SetField2;
   property Field3: String read GetField3 write SetField3;
   property Field4: String read GetField4 write SetField4;
 end;

 TForm1 = class(TForm)
   Button1: TButton;
   Button2: TButton;
   Memo1: TMemo;
   procedure Button1Click(Sender: TObject);
   procedure Button2Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;
 PusikSample: TPusikSample;

implementation

{$R *.dfm}

{ TPusikSample }

constructor TPusikSample.Create;
begin
 FCS := TCriticalSection.Create;
end;

destructor TPusikSample.Destroy;
begin
 FCS.Free;
 inherited;
end;

function TPusikSample.GetField1: String;
begin
 Lock;
 try
   Result := FField1;
 finally
   Unlock;
 end;
end;

function TPusikSample.GetField2: String;
begin
 Lock;
 try
   Result := FField2;
 finally
   Unlock;
 end;
end;

function TPusikSample.GetField3: String;
begin
 Lock;
 try
   Result := FField3;
 finally
   Unlock;
 end;
end;

function TPusikSample.GetField4: String;
begin
 Lock;
 try
   Result := FField4;
 finally
   Unlock;
 end;
end;

procedure TPusikSample.Lock;
begin
 FCS.Enter;
end;

procedure TPusikSample.OnTerminateThread(Sender: TObject);
begin
 ShowMessage("Расчет завершен");
end;

procedure TPusikSample.SetField1(const Value: String);
begin
 Lock;
 try
   FField1 := Value;
 finally
   Unlock;
 end;
end;

procedure TPusikSample.SetField2(const Value: String);
begin
 Lock;
 try
   FField2 := Value;
 finally
   Unlock;
 end;
end;

procedure TPusikSample.SetField3(const Value: String);
begin
 Lock;
 try
   FField3 := Value;
 finally
   Unlock;
 end;
end;

procedure TPusikSample.SetField4(const Value: String);
begin
 Lock;
 try
   FField4 := Value;
 finally
   Unlock;
 end;
end;

procedure TPusikSample.StartThread;
begin
 FThread := TPusikThread.Create(Self);
 FThread.OnTerminate := OnTerminateThread;
 FThread.Resume;
end;

procedure TPusikSample.Unlock;
begin
 FCS.Leave;
end;

{ TPusikThread }

constructor TPusikThread.Create(aParent: TPusikSample);
begin
 inherited Create(True);
 FreeOnTerminate := True;
 FPusikSample := aParent;
end;

procedure TPusikThread.Execute;
begin
 Sleep(1000);
 FPusikSample.Field1 := "Расчет на шаге 1 закончен";
 Sleep(1000);
 FPusikSample.Field2 := "Расчет на шаге 2 закончен";
 Sleep(1000);
 FPusikSample.Field3 := "Расчет на шаге 3 закончен";
 Sleep(1000);
 FPusikSample.Field4 := "Расчет на шаге 4 закончен";
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 PusikSample := TPusikSample.Create;
 PusikSample.StartThread;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
 Memo1.Lines.Clear;
 Memo1.Lines.Add(PusikSample.Field1);
 Memo1.Lines.Add(PusikSample.Field2);
 Memo1.Lines.Add(PusikSample.Field3);
 Memo1.Lines.Add(PusikSample.Field4);
 PusikSample.Free;
end;

end.


 
Leonid Troyanovsky ©   (2006-06-29 01:02) [8]


> Fay ©   (29.06.06 00:14) [5]

> Ничего не скажу. Не использую TThread-идов.

> Джо ©   (29.06.06 00:24) [6]

> Я, хоть и не "ярый поклонник", но изпользую TTread"ы и считаю
> их чертовски удобными :-)


Понимаю, согласен  :)

Жаль вот лишь, что ярые поклонники не реагируют.

--
Regards, LVT.


 
Leonid Troyanovsky ©   (2006-06-29 02:16) [9]


> Пусик ©   (29.06.06 00:57) [7]

> ООП так ООП.

> Вот пример:


Не понравился.
Во-первых, какие-то приседания вокруг непонятного TPusikSample,
когда это должен быть простой потомок TThread.
Во-вторых, странно, что поборники ООП, видимо, не знакомы
с индексированными свойствами.
Да, и сама идея с критической секцией в данном случае выглядит
громоздко и неестественно против Synchronize.

Да, и какое такое агрегирование?

--
Regards, LVT.


 
Джо ©   (2006-06-29 02:29) [10]

> Да, и какое такое агрегирование?

Наверное, агрегация (хотя я встречал и вариант "агрегирование"). Только я и сам не очень пойму, почему не использовано наследование, но тут уж хозяин барин. Возможно, и были причины, я код не смотрел, только объявления.


 
Пусик ©   (2006-06-29 02:34) [11]


> когда это должен быть простой потомок TThread.


1. Простой потомок TThread сможет выполнить поточную функцию только один раз. В примере поток создается по мере необходимости. К тому же в классе может бытьнеобходимость в создании нескольких разных потоков.
2. Условие в топике предполагает именно такое решение.


> Во-вторых, странно, что поборники ООП, видимо, не знакомыс
> индексированными свойствами.


Противники ООП видимо забывают, что здесь поборники ООП приводят примеры. В приведенном примере поля FField1..4 могут быть разного типа.


> Да, и сама идея с критической секцией в данном случае выглядитгромоздко
> и неестественно против Synchronize.


В данном случае решение с критической секцией намного элегантнее и проще. Для Synchronize потребовалось бы либо писать дополнительно 4 функции для работы с каждым полем по-отдельности, либо исользовать промежуточные/временные поля. В случае 5-10... и т.д. количества полей и алгоритмом расчета по шагам с синхронизацией на каждом шаге с Synchronize вообще не подходит.


> Да, и какое такое агрегирование?


Нууу...

Такие вещи, я бы сказала, просто стыдноне знать...

В традиционном ООП предусмотрены три типа отношений между классами:
- Использование: непосредственная зависимость.
- Включение: иногда называется агрегированием. Реализует логические связи типа «является составной частью».
- Наследование: реализует логические связи типа «является частным случаем».

В таких языках, как VB .NET, C# и Java, кроме классических типов существует четвертый тип отношений между классами — реализация интерфейса (отношение типа «поддерживает»).


 
Игорь Шевченко ©   (2006-06-29 09:45) [12]


> В таких языках, как VB .NET, C# и Java, кроме классических
> типов существует четвертый тип отношений между классами
> — реализация интерфейса (отношение типа «поддерживает»).
>


В Delphi тоже...


 
Leonid Troyanovsky ©   (2006-06-29 18:39) [13]


> Пусик ©   (29.06.06 02:34) [11]


> 1. Простой потомок TThread сможет выполнить поточную функцию
> только один раз. В примере поток создается по мере необходимости.
>  К тому же в классе может бытьнеобходимость в создании нескольких
> разных потоков.

Ну, и юзай поля-свойства формы - это ж, всего лишь, пример.

> приводят примеры. В приведенном примере поля FField1..4
> могут быть разного типа.

Да - споткнулся, упал на нож. И так 13 раз подряд.

> В данном случае решение с критической секцией намного элегантнее
> и проще. Для Synchronize потребовалось бы либо писать дополнительно
> 4 функции для работы с каждым полем по-отдельности, либо

А зачем 4? Одной вполне достаточно.
Да и полей хватит, можно даже без свойств.

Т.е., весь этот пример можно было свести к десятку строк.
И мысли б были понятней, и мне б, возможно понравилось.
Краткость, как говорится, сестра.

> Такие вещи, я бы сказала, просто стыдноне знать...

Не зарывайтесь, Штирлиц. Не зарывайтесь.
Я старше Вас по возрасту, да и по званию.

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

Но, конечно, после разъяснения - мол, проблемы с
агрегированием - мне сразу стало раза в два понятней.

> В традиционном ООП предусмотрены три типа отношений между

Думаю, что в нетрадиционном их даже более.

--
Regards, LVT.


 
Пусик ©   (2006-06-29 19:02) [14]


> Leonid Troyanovsky ©   (29.06.06 18:39) [13]
> возрасту, да и по званию.


Позвольте поинтересоваться Вашим возрастом и званием?


 
Fay ©   (2006-06-29 19:07) [15]

2 Пусик ©   (29.06.06 19:02) [14]
5+


 
Пусик ©   (2006-06-29 19:12) [16]


> Leonid Troyanovsky ©   (29.06.06 18:39) [13]


Целью выше приведенного кода являлось показать пример, как делаетсяф то, что нужно автору. А понравится этот код или нет LVT, мне, в принципе, абсолютно фиолетово.
Всегда проще критиковать чужой код, чем написать свой.
А как использовать показанные приемы - личное дело автора вопроса.


 
Leonid Troyanovsky ©   (2006-06-29 19:49) [17]


> Пусик ©   (29.06.06 19:02) [14]

> Позвольте поинтересоваться Вашим возрастом и званием?


Лейтенант я, старшой.. Угу.

45 полных (23 стаж, застал ЕС1055 и IBM355,
правда, в японской войне не участвовал)

--
Regards, LVT.


 
Leonid Troyanovsky ©   (2006-06-29 19:56) [18]


> Пусик ©   (29.06.06 19:12) [16]

> Всегда проще критиковать чужой код, чем написать свой.


Заблуждение.
Иногда читаешь нечто и думаешь, чего ж так автор мучается,
проще уж самому написать.

Но, есть, конечно, и хорошие примеры - льются как песня.

Так, вот, уважаемый Пусик - стремиться надо к последним.
Это я тебе как старший товарищ говорю.

--
Regards, LVT.


 
Fay ©   (2006-06-29 20:03) [19]

2 Leonid Troyanovsky ©   (29.06.06 19:56) [18]
Приведите свой пример-песню. Заодно укажете направление для устремлений.


 
Leonid Troyanovsky ©   (2006-06-29 20:47) [20]


> Fay ©   (29.06.06 20:03) [19]

> Приведите свой пример-песню. Заодно укажете направление
> для устремлений.


Мне нравятся примеры by Peter Below (TeamB).
Можешь нагуглить на многие темы.

Один зарубежный дельфер даже создал коллекцию из
его постов в chm (5-6MB). Очень увлекательно читается.

Ну, а устремление у нас должно быть одно:
каждый день, каждый час играть в шаш.., т.е. шахматы.

--
Regards, LVT.



Страницы: 1 вся ветка

Текущий архив: 2006.07.16;
Скачать: CL | DM;

Наверх




Память: 0.54 MB
Время: 0.036 c
2-1151473229
greg123
2006-06-28 09:40
2006.07.16
вопрос по xml


4-1144178421
Кашперук Иван
2006-04-04 23:20
2006.07.16
Какой максимальный размер строки в реестре (REG_SZ)


1-1148703455
tio
2006-05-27 08:17
2006.07.16
MDI правильное закрытие окон и исчезновением их


2-1151671180
Gizza
2006-06-30 16:39
2006.07.16
База данных


2-1151290523
learner
2006-06-26 06:55
2006.07.16
Передача функции класса как параметра в др. функцию