Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.05.02;
Скачать: [xml.tar.bz2];

Вниз

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

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

Наверх




Память: 0.48 MB
Время: 0.039 c
3-1081189645
leonidus
2004-04-05 22:27
2004.05.02
Проблема с кодировкой DBF


8-1075539418
Millennium
2004-01-31 11:56
2004.05.02
скриншот


3-1081419593
ev
2004-04-08 14:19
2004.05.02
Как через SQL запрос найти значения подстроки, без учета регистра


14-1081224495
Vlad Oshin
2004-04-06 08:08
2004.05.02
Уважаемые Питерцы! Помогите с жильем...


7-1074534422
DelphiN!
2004-01-19 20:47
2004.05.02
Получить инормацию о соединениях





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский