Форум: "Основная";
Текущий архив: 2005.06.29;
Скачать: [xml.tar.bz2];
ВнизЕще раз потоки Найти похожие ветки
← →
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;
end.
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;
← →
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;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.058 c