Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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;

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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.062 c
14-1117491469
KilkennyCat
2005-05-31 02:17
2005.06.29
Если кому нужна работа в Петербурге


1-1118051551
SergeiX
2005-06-06 13:52
2005.06.29
как убрать разбиение на страницы


14-1117781079
Jeer
2005-06-03 10:44
2005.06.29
МПК "Эльбрус"


14-1117204178
Сатир
2005-05-27 18:29
2005.06.29
У кого есть фотка команды Microsoft 78-го года ?


1-1118217103
TAN_K
2005-06-08 11:51
2005.06.29
PageControl и PageControl





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский