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

Вниз

Еще раз потоки   Найти похожие ветки 

 
Gek1   (2005-06-02 12:11) [0]

Мастера, раскажите пожалуйста как делаються следующие вещи:
1. Обмен данных между потоками через PostThreadMessage
Т.е имеется ввиду обмен данных произвольной структуры. Как правильно отправлять? Как корректно принимать?
Хотелось бы на код глянуть.

2. Использование TClientSocket в потоке:
Могу ли я создав сокет в доп. потоке использовать его события (OnConnect, OnRead, OnEror) и там же обрабатывать? Или же мне надо периодически вручную это делать?


 
TUser ©   (2005-06-02 12:16) [1]

1. Я думаю, WM_COPYDATA поможет
2. Я думаю, да


 
Defunct ©   (2005-06-02 12:21) [2]

1. Сообщить что данные есть. Второй поток пусть их забирает. Предусмотреть защиту данных через крит. секцию.
2. Да без проблем.

TUser ©   (02.06.05 12:16) [1]

WM_COPYDATA можно использовать только в связке с SendMessage


 
Alexander Panov ©   (2005-06-02 12:22) [3]

TUser ©   (02.06.05 12:16) [1]
Gek1   (02.06.05 12:11)

Ну внутри одного процесса необязатально использовать WM_COPYDATA.

Можно использовать любое пользовательское сообщение, а в сообщении передавать адрес данных, которые нужно обработать.

Для работы с очередью сообщений внутри потока ее нужно организовать.

простейший пример:

procedure TTestThread.Execute;
begin
 PeekMessage(FMsg,0,0,0,PM_NOREMOVE);
 while not Terminated do
 begin
   GetMessage(FMsg,0,0,0);
   case FMsg.message of
     MyM_Test:
       begin
         FMessage := "New Message!";
         Synchronize(Display);
       end;
     WM_QUIT:
       begin
         FMessage := "Hmm... Terminate thread!";
         Synchronize(Display);
         Terminate;
       end;
   end;
 end;
end;


 
Gek1   (2005-06-02 13:28) [4]

Раз все сказали на второй вопрос "Да" , такой вопрос:
Как в случае [3] будут генерироваться и обрабатыватся события от сокета, если сам код будет все время вертется только в TTestThread.Execute?

Alexander Panov ©   (02.06.05 12:22) [3]
А можете привести как и приемную так и передающую сторону?


 
Digitman ©   (2005-06-02 13:48) [5]


> Как в случае [3] будут генерироваться и обрабатыватся события
> от сокета, если сам код будет все время вертется только
> в TTestThread.Execute?


обычным образом.
НИКАКИХ отличий от варианта, когда то же самое происходит осн.трэде.

Трэды процесса вообще ничем не отличаются с прикл.точки зрения.


 
Gek1   (2005-06-02 13:56) [6]

Digitman ©   (02.06.05 13:48) [5]
Основной тред построен на событиях.
Событие обработалось и тред ждет новых событий.

В доп. потоке - я там зацикленно буду сидеть в TTestThread.Execute. Поэтому и возник вопрос [4]


 
Digitman ©   (2005-06-02 14:05) [7]


> Gek1   (02.06.05 13:56) [6]
> Основной тред построен на событиях


не на событиях, а не win-сообщениях.
претензии - к Борланду.


>  я там зацикленно буду сидеть в TTestThread.Execute


ну и сиди себе !

чем это мешает своевременной реакции на события гнездового транспорта ?

ничем.


 
evvcom ©   (2005-06-02 14:11) [8]


> В доп. потоке - я там зацикленно буду сидеть в TTestThread.Execute.

Посмотри код TApplication.Run, там тоже цикл. А как иначе?


 
Digitman ©   (2005-06-02 14:15) [9]


> Gek1   (02.06.05 13:56) [6]


хочешь хороший совет ?

забудь на время про доп.потоки.

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

и пусть тебе нужно и использовать в нем TClientSocket безо всяких выкрутасов с доп.потоками

реши эту задачу ! и будет все в шоколаде)

все что у тебя заработало в консоли между begin..end. , точно так же будет работать (безо всяких изменений !) в теле TThread.Execute ..

синхронизацию доступа к VCL-объектам со стороны доп.потоков, естественно, не рассматриваем в дан.случае как не существенный момент.


 
Gek1   (2005-06-02 15:10) [10]

evvcom ©   (02.06.05 14:11) [8]
можешь показать его? у меня нету forms.pas?

Digitman ©   (02.06.05 14:15) [9]
не понимаю как может обработаться событие без Application.ProcessMessage? Учитывая что поток все время чтото делает. Тем более для дополнительного потока помоему нельзя использовать Application.ProcessMessage.


 
Digitman ©   (2005-06-02 15:17) [11]


> не понимаю как может обработаться событие без Application.ProcessMessage?
>


заглянуть в текст реализации метода - не судьба ?

и вообще - на объекте Application свет клином сошелся ?
без него уже никак ? или ЕЩЕ никак ?)


> для дополнительного потока помоему нельзя использовать Application.ProcessMessage


да мало ли чего там нельзя !)

но ведь никто не заставляет тебя использовать это дело в осн.потоке, хоть там и "можно" ?


 
Alexander Panov ©   (2005-06-02 15:30) [12]

unit Unit1;

interface

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

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

var
 Form1: TForm1;
 Reader: TMyReader;
 Writer: TMyWriter;

implementation

{$R *.dfm}

procedure DispMessage(aMsg: PMsgData);
begin
 Form1.Memo1.Lines.Add(aMsg^.Str);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 Reader := TMyReader.Create(DispMessage);
 Writer := TMyWriter.Create(Reader.ThreadID,1000);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
 Writer.Terminate;
end;

end.

unit Unit2;

interface

uses
 Classes, SysUtils, windows, Messages;

const
 WM_MYMESSAGE=WM_USER+1;
type

 PMsgData=^TMsgData;

 TMsgData=record
   Str: String;
 end;

 TDisplayProcedure=procedure(aMsg: PMsgData);

 TMyWriter = class(TThread)
 private
   FThreadIdReader: THandle;
   FTime: Cardinal;
   FData: PMsgData;
 protected
   procedure Execute; override;
 public
   constructor Create(aThreadId: THandle;aTime: Cardinal);
 end;

 TMyReader = class(TThread)
 private
   FMSg: TMsg;
   FData: PMsgData;
   FDisplayProc: TDisplayProcedure;
   procedure Display;
 protected
   procedure Execute; override;
 public
   constructor Create(Proc: TDisplayProcedure);
 end;

implementation

{ TMyReader }

constructor TMyReader.Create(Proc: TDisplayProcedure);
begin
 inherited Create(True);
 FDisplayProc := Proc;
 FreeOnterminate := True;
 Resume;
end;

procedure TMyReader.Display;
begin
 if Assigned(FDisplayProc) then
 begin
   FDisplayProc(FData);
   Dispose(FData);
 end;
end;

procedure TMyReader.Execute;
begin
 PeekMessage(FMsg,0,0,0,PM_NOREMOVE);
 while not Terminated do
 begin
   GetMessage(FMsg,0,0,0);
   case FMsg.message of
     WM_MYMESSAGE:
     begin
       FData := PMsgData(FMsg.wParam);
       Synchronize(Display);
     end;
     WM_QUIT: Terminate;
   end;
end;
end;

{ TMyWriter }

constructor TMyWriter.Create(aThreadId: THandle; aTime: Cardinal);
begin
 inherited Create(True);
 FThreadIdReader := aThreadId;
 FTime := aTime;
 FreeOnterminate := True;
 Resume;
end;

procedure TMyWriter.Execute;
begin
 while not Terminated do
 begin
   FData := nil;
   New(FData);
   FData.Str := FormatDateTime("dd.mm.yyyy hh:nn:ss",now);
   PostThreadMessage(FThreadIdReader,WM_MYMESSAGE,Integer(FData),0);
   Sleep(FTime);
 end;
 PostThreadMessage(FThreadIdReader,WM_QUIT,Integer(FData),0);
end;

end.


 
evvcom ©   (2005-06-02 16:17) [13]


> можешь показать его? у меня нету forms.pas?

procedure TApplication.Run;
begin
...
     repeat
       try
         HandleMessage;
       except
         HandleException(Self);
       end;
     until Terminated;
...
end;

procedure TApplication.HandleMessage;
var
 Msg: TMsg;
begin
 if not ProcessMessage(Msg) then Idle(Msg);
end;

procedure TApplication.Idle(const Msg: TMsg);
var
 Done: Boolean;
begin
 ...
 Done := True;
 ...
 if Done then WaitMessage;
end;


 
Игорь Шевченко ©   (2005-06-02 16:34) [14]

Alexander Panov ©   (02.06.05 15:30) [12]

Сурово



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

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

Наверх




Память: 0.51 MB
Время: 0.029 c
14-1117682224
Kerk
2005-06-02 07:17
2005.06.29
С днем рожденья! 2 июня


14-1117702754
КаПиБаРа
2005-06-02 12:59
2005.06.29
Какой из методов обучения более правильный?


11-1101454403
TKV
2004-11-26 10:33
2005.06.29
Прооблема с BapTrayIcon при запуске приложения выдает ошибку 216.


9-1111554916
Starter
2005-03-23 08:15
2005.06.29
Несколько видов


3-1116581962
Naganov
2005-05-20 13:39
2005.06.29
Промежуточные вычисления в EhGrid e