Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Многопочность при работе с портами ПК [D6, WinXP]


Страницы:   1 2

Gugle ©   (2005-10-17 12:26:00) 

Доброго  времени суток!
Столкнулся с некоторыми проблемами при работе с многопоточностью. Много потоков создаю при работе не с файлами, а с различными портами ПК. Программа постоянно что передает и принимает от удаленных устройств и если делать все в одном потоке она постоянно висит (т.е. занята), в определенные промежутки времени (решает пользователь) необходимо прервать тот или иной поток!

Создаю отдельный класс (TMyThread = class(TThread)). Делаю в нем несколько процедур и запускаю его отдельным потоком (MyThread:=TMyThread.Create(False)) и потом пытаюсь этот поток прервать (MyThread.Free).

Что вижу:
1. Проседура (procedure Execute; override) внутри которой происходят основные вычисления вроде как останавливается, однако память она продолжает забивать (видимо поток внутри памяти продолжает пахать).
2. Процедуры и функции вне (procedure Execute; override) работают хоть и последовательно, но не внутри самого потока и для них выделяется память отдельно (вообще такое ощущение что запускается в потоке не весь класс, а просто "procedure Execute".
3. При попытке остановки потока (MyThread.Free) память не освобождается и мало того программа основного потока занята темы процедурами и функциями которые находятся вне "procedure Execute", но в самом классе ТMyThread, с чего вдруг непонятно?!?

Теперь вопросы:
1. Работа отдельно потока запущеного через отдельный класс происходит ТОЛЬКО в "procedure Execute" или нет?
2. Как, не только отпустить поток, но и освободить память которая была выделана под этот поток?
3. Если на первый вопрос "Да", то как остановить работу всего класса и вообще возможно это или нет?

Не уверен что нужен код самой программы поэтому кину программу на которой тестирую эти потоки:
(Он сильно урезан от основного кода и тут работа только с одним COM-портом. Процедуры иниациализации потра и определения его параметров думаю ненужны, но они есть и выполняются не в классе ТMyThread, а в основном потоке)

По программе:
Unit1:
1. Есть форма на ней пару кнопок. Button1 - запускает дополнительный поток, Button2 - останавливает его.
2. В Edit1 и Edit3 - вывод результатов математических вычислений из разных мест программы и разными методами. Edit2 - нужен для того, что бы быть уверенным что при запуске дополнительного потока, основной не занят.


procedure TForm1.Button1Click(Sender: TObject);
begin
 StartThrd;
end;

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



Unit2:
Собственно тут и реализован отдельный класс и его работа.


unit Unit2;

interface

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

type
 TMyThread = class(TThread) //Новый класс
 procedure ShowResult;
 private
   answer: Integer;
 protected
   Procedure WriteStrToPort;
   procedure Execute; override;
 end;

var MyThread:TMyThread;
   answer: Integer;

procedure StartThrd;
Procedure StopThrd;

implementation

procedure TMyThread.ShowResult;
begin
 Form1.Edit1.Text := IntToStr(answer);
end;

procedure TMyThread.Execute;
var
 i: Integer;
begin
 for i := 1 to 100000 do
 begin
   answer := answer + 1;
//    MyThread.ShowResult;
//    MyThread.WriteStrToPort;
   Form1.Edit3.Text := IntToStr(answer);
   Synchronize(WriteStrToPort);
   Synchronize(ShowResult);
 end;
end;

Procedure TMyThread.WriteStrToPort;
Var
MyBuff: Array[0..1023] Of Char;
ByteWritten, ByteReaded: Cardinal;
DataFull : String;
hPort:Integer;
Begin
  DataFull := IntToStr(answer);
  FillChar(MyBuff,SizeOf(MyBuff),#0);          //готовим буфер для передачи
  DataFull:=DataFull;
  StrPCopy(MyBuff,DataFull);                   //передаем данные в буфер

  WriteFile(hPort,MyBuff,Length(DataFull),ByteWritten,Nil);   //передаем данные

  // Читаем буфер из com-порта
  FillChar(MyBuff,SizeOf(MyBuff),#0);
  ReadFile(hPort,MyBuff,SizeOf(MyBuff),ByteReaded,Nil);
end;

procedure StartThrd;
begin
 MyThread:=TMyThread.Create(False);
 If MyThread = Nil Then
 Begin {Nil}
     //ошибка, все выключаем и выходим
     SysErrorMessage(GetLastError);
     Exit;
 End; {Nil}
end;

procedure StopThrd;
begin
 MyThread.Free;
end;

end.


Ну, вот собственно и все. Заранее всем благоданет!


Leonid Troyanovsky   (2005-10-17 14:36:00) [21]


> Gugle ©   (17.10.05 14:08) [6]

> Digitman ©   (17.10.05 13:02) [5]

> Спасибо!


Можно нескромный вопрос?
А почему "спасибо" только уважаемому Digitman © ?
И только за  (17.10.05 13:02) [5] ?
Т.е., про остальное не стоило и спрашивать?

--
Regards, LVT.


Gugle   (2005-10-17 14:08:00) [22]


Digitman ©   (17.10.05 13:02) [5]


Спасибо!


Digitman   (2005-10-17 13:02:00) [23]


> Gugle ©   (17.10.05 12:52) [4]


> почему Synchronize не использовать?


никто не запрещает его использовать.

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


Gugle   (2005-10-17 12:52:00) [24]

Хм...

Ну по поводу
Form1.Edit3.Text := IntToStr(answer);
и
 MyThread = Nil
согласен!

А почему Synchronize не использовать? (Если конечно это можно объяснить в краце или просто поверить профи?)


Fay   (2005-10-17 12:46:00) [25]

2 REA   (17.10.05 12:39) [2]
>> 2) Synchronize не рекомендую использовать в потоках
Почему?


REA   (2005-10-17 12:39:00) [26]

1) внутри потока надо постоянно проворять свойство Terminated и выходить при true
2) Synchronize не рекомендую использовать в потоках
3) MyThread = Nil. Это как?
4) Form1.Edit3.Text := IntToStr(answer); - вот этого не надо делать
5) Synchronize(WriteStrToPort) - и этого


Digitman   (2005-10-17 12:36:00) [27]

для начала убери серьезную допущенную тобой ошибку, связанную с обращением к Form1.Edit3.Text в доп.потоке


Страницы:   1 2

Наверх

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