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

Вниз

Поток и все все все...   Найти похожие ветки 

 
NeyroSpace ©   (2004-04-16 23:52) [0]

Я с потоками еще не практиковался, поэтому ламерский вопрос...
Я хочу, чтобы DLL создавала свой поток, который работая с приоритетом tpIdle и занимая как можно меньше процессорного времени выполнял вызов CallBack процедуры, но не простой а с передачей параметров в эту процедуру. Делаю для чтения данных из мэйлслота, но так ведь можно проверять, что угодно, например появление нового файла в каталоге. Главная задача не нагружать процессор.

library mydll;

uses
 sysutils,
 Classes;

type
 TMailSlotThread = class(TThread)
 private
   { Private declarations }
 protected
   procedure Execute; override;
 end;

var
  RunCallBackFunction : TThreadMethod;
  MSThread : TMailSlotThread;

{ TMailSlotThread }

procedure TMailSlotThread.Execute;
begin
 { Place thread code here }
While not Terminated do
 begin
 Synchronize(RunCallBackFunction);
//            ^^^^^^^^^^^^^^^^^^^-- вот здесь хотелось бы
//  Synchronize(RunCallBackFunction(something));//так :-)
//  т.е. поток не просто вызывает CallBack процедуру, а еще
//  толкает туда что-то.
 end;
end;

function Start(CallBackFunction:TThreadMethod):PChar;
begin
//получаем адрес CallBackFunction и сохраняем его в глоб. перем.
RunCallBackFunction := CallBackFunction;

if MSThread = nil then
 begin
 MSThread := TMailSlotThread.Create(true);
 MSThread.Priority := tpTimeCritical;//tpIdle, tpLowest, tpLower, tpNormal,
                                     // tpHigher, tpHighest, tpTimeCritical
 MSThread.Resume;
 result := "MSThread создан и запущен!";
 end
 else
 result:="Не могу создать MSThread, т.к. он уже создан!";
end;

function Stop():PChar;
begin
result := "MSThread уже давно убит!";
if MSThread <> nil then
 begin
 MSThread.Terminate;
 MSThread.Free;
 MSThread := nil;
 result := "MSThread.Terminate! MSThread.Free!"
 end;
end;

exports
Start index 1  name "Start",
Stop index 2  name "Stop";
end.
-----------------------------------------------------------------
Соответственно в Project"е:
-----------------------------------------------------------------
unit Unit1;

interface

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

type
 TForm1 = class(TForm)
   Button1: TButton;
   Edit1: TEdit;
   Button2: TButton;
   procedure Button1Click(Sender: TObject);
   procedure Button2Click(Sender: TObject);
//    PROCEDURE CallBackFromDll(var getcounter:cardinal);
   PROCEDURE CallBackFromDll;
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;
 getcounter:integer;

implementation

{$R *.DFM}
function Start(CallBackFunction:TThreadMethod):PChar;stdcall;external "../mydll.dll" name "Start";
function Stop():PChar;stdcall;external "../mydll.dll" name "Stop";

PROCEDURE TForm1.CallBackFromDll;
BEGIN
Form1.Caption := inttostr(getcounter);
inc(getcounter);
//пока просто крутим счетчик :-)
END;

procedure TForm1.Button1Click(Sender: TObject);
begin
getcounter := 0;
edit1.text:=Start(Form1.CallBackFromDll);
//                ^^^^^^^^^^^^^^^^^^^^^---эту проц. будет вызывать поток
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
edit1.text:=Stop();
end;

end.
-----------------------------------------------------------------
Возникли следующие вопросы:
1. Как сделать это Synchronize(RunCallBackFunction(something)) сделать?
2. Почему меняя приоритеты потока, не видно разницы в скорости?
3. Почему tpIdle загружает систему на 99%?
Что ошибка в ДНК уже знаю :-)


 
DrPass ©   (2004-04-17 00:04) [1]

Приоритет потока определяет не процент загрузки процессора, а всего лишь долю процессорного времени, которое будет отведено потоку. Если ты хочешь сделать поток "ненапряжным", используй функцию sleep. Synchronize же вообще выполняет код в контексте основного потока программы, и это очень ресурсоемкая операция. Ну а параметры тип ThreadMethod не предполагает. Если сильно нужно, можно попробовать использовать глобальные переменные


 
Игорь Шевченко ©   (2004-04-17 00:05) [2]


> Делаю для чтения данных из мэйлслота


ReadFile + Overlapped

While not Terminated do
begin
Synchronize(RunCallBackFunction);
end;

Так делать не надо, весь смысл введения дополнительного потока пропадает


 
NeyroSpace ©   (2004-04-17 00:42) [3]

Все должно крутится в ДЛЛ (можно считать, что ДЛЛ это плагин), а когда произойдет событие, вызовется та самая процедура из основного ЕХЕ. Она должна получить только результат.
Например, как я уже сказал: длл ждет появления файла в каталоге. Как только он появился вызывается одна ф-ция из ЕХЕ.


 
NeyroSpace ©   (2004-04-17 00:51) [4]

Т.е. в самом ехе я уже знаю, что процедура выполнится только если файл в каталоге появился. Это как OnMouseClick что ли.


 
Игорь Шевченко ©   (2004-04-17 01:09) [5]


> длл ждет появления файла в каталоге


ReadDirectoryChangesW ?


 
DrPass ©   (2004-04-17 01:18) [6]

Если программа будет работать только на NT-шных системах, то лучше всего
> Игорь Шевченко ©   (17.04.04 01:09) [5]

Если же Win9x (или сильно хочется использовать поток), то лучше не использовать Synchronize и callback"и - просто пошли какое-нибудь сообщение окну программы через PostMessage.


 
KSergey ©   (2004-04-17 07:01) [7]

1. Как сделать это Synchronize(RunCallBackFunction(something)) сделать?

Завести переменную (-ные) внутри класса потока, работать через них.

2. Почему меняя приоритеты потока, не видно разницы в скорости?

А теперь параллельно запусти архивирование (или любой другой процесс) - и посмотри что изменится. Так. же см. начало из [1] DrPass ©   (17.04.04 00:04)

> [1] DrPass ©   (17.04.04 00:04)
> Приоритет потока определяет не процент загрузки процессора,
> а всего лишь долю процессорного времени, которое будет отведено
> потоку. Если ты хочешь сделать поток "ненапряжным", используй
> функцию sleep. Synchronize же вообще выполняет код в контексте
> основного потока программы, и это очень ресурсоемкая операция.

Дело даже не в том, что Synchronize "это очень ресурсоемкая операция". А в том, что код потока Execute, состоящий из Synhronize смысла не имеет! См. в любой книжке подробности что это за метод и как он работает, а так же архивы форума: обсуждение было, не раз. Часто - весьма бурное. Примерно месяц-два назад - точно что-то было. Еще статья на данном сайте хаялась про потоки.



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

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

Наверх




Память: 0.49 MB
Время: 0.032 c
1-1082348046
Никита
2004-04-19 08:14
2004.05.02
Конвертирование HTML в RTF


14-1081426797
lepton77
2004-04-08 16:19
2004.05.02
А где новые дайджесты форумов?


1-1082291310
killer
2004-04-18 16:28
2004.05.02
перевод из строки в TStringList


14-1081878366
Ig
2004-04-13 21:46
2004.05.02
Создание компонент в Delphi !?


14-1081857543
WELLiON
2004-04-13 15:59
2004.05.02
файл-менеджер