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

Вниз

CreateThread(nil,0,@MyProcedure,0,0,nil);   Найти похожие ветки 

 
Tolik   (2006-01-19 21:22) [0]

Как передать свои параметры п процедуру?
например CreateThread(nil,0,@MyProcedure(1,1,2),0,0,nil); ?


 
begin...end ©   (2006-01-19 21:42) [1]

> Tolik   (19.01.06 21:22)

type
 PParam = ^TParam;
 TParam = record
   First, Second, Third: Integer
 end;

function MyFunction(P: Pointer): Integer; stdcall;
var
 Data: TParam;
begin
 Data := PParam(P)^;
 // Теперь в Data скопированы данные,
 // указатель на которые был передан в функцию
 ...
 Result := ...;
end;

var
 Param: TParam;
 hThread, ThreadId: Cardinal;

begin
 Param.First  := 1;
 Param.Second := 1;
 Param.Third  := 2;
 hThread := CreateThread(nil, 0, @MyFunction, @Param, 0, ThreadId);
 ...
end


Переменная Param не должна удаляться из памяти во время работы потока. Если её случится (например, при выходе из подпрограммы, в которой она объявлена), её адрес станет недействительным, и попытка обратиться к данным по этому адресу внутри поточной функции приведёт к ошибке. Впрочем, это же касается и переменных hThread и ThreadId -- первая из них потребуется для закрытия хэндла потока, а вторая может быть использована для получения кода его завершения.

И ещё: уж сколько раз твердили миру -- используйте BeginThread вместо CreateThread. Почему -- см. справку по BeginThread.


 
begin...end ©   (2006-01-19 21:52) [2]

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

Сорри, это я погорячился -- для этого Id напрямую использован быть не может. Но если идентификатор будет нужен для иных целей, "предостережение" остаётся в силе.

> Если её случится...

Если это случится...

P.S. Да, preview бы не помешал...


 
Tolik   (2006-01-19 22:11) [3]

Интересная штука получилась
function MyFunction(P: Pointer): Integer; stdcall;
var
Data: TParam;
i:integer;
begin
Data := PParam(P)^;
Result := Data.First;
for i:=0 to result do
begin
Form1.Memo1.Lines.Add(IntToStr(i));
// Теперь в Data скопированы данные,
// указатель на которые был передан в функцию }
end;
end;

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


 
begin...end ©   (2006-01-19 22:12) [4]

> Tolik   (19.01.06 22:11) [3]

Не понял, в чём проблема. Зато вижу обращение к VCL из неосновного потока.


 
Tolik   (2006-01-19 22:13) [5]

Наверно тоже понадобится
type
PParam = ^TParam;
  TParam = record
  First, Second, Third: Integer
end;

и код батонаprocedure TForm1.Button1Click(Sender: TObject);
var
Param: TParam;
hThread, ThreadId: Cardinal;
begin
 Param.First  := 100;
//Param.Second := 1;
//Param.Third  := 2;

hThread := BeginThread(nil, 0, @MyFunction, @Param, 0, ThreadId);

end;


 
Tolik   (2006-01-19 22:14) [6]

На мемо выходит переменная i,которая равна 100.Так на мемо выходит то 106 то 110 то 115.Почему так?


 
begin...end ©   (2006-01-19 22:19) [7]

> Tolik   (19.01.06 22:13) [5]

Во-первых, поскольку используете BeginThread, то соглашение о вызове функции MyFunction должно быть другим (уберите stdcall).

Во-вторых, я же ясно сказал в [1], что Param не должна удаляться из памяти. А Вы сделали её локальной переменной обработчика -- как только BeginThread запустит поток, обработчик завершится, и переменная Param перестанет существовать.


 
Tolik   (2006-01-19 22:23) [8]

Кхе,следствие зашло в тупик:)

var
 Form1: TForm1;

implementation

{$R *.dfm}
var
 th1, th2: cardinal;
 h1, h2: integer;

type
PParam = ^TParam;
  TParam = record
  First, Second, Third: Integer
end;

function MyFunction(P: Pointer): Integer;
var
Data: TParam;
i:integer;
begin
Data := PParam(P)^;
Result := Data.First;
for i:=0 to result do
begin
Form1.Memo1.Lines.Add(IntToStr(i));
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
Param: TParam;
hThread, ThreadId: Cardinal;
begin
Param.First  := 100;
Param.Second := 1;
Param.Third  := 2;
hThread := BeginThread(nil, 0, @MyFunction, @Param, 0, ThreadId);

end;

не трудно ли будет сказать,как сделать Param глобальной


 
begin...end ©   (2006-01-19 22:27) [9]

> Tolik   (19.01.06 22:23) [8]

> не трудно ли будет сказать,как сделать Param глобальной

Вынести за пределы обработчика Button1Click, очевидно. Вот сюда:

var
 th1, th2: cardinal;
 h1, h2: integer;
 Param: TParam;
 hThread: Cardinal;


 
Tolik   (2006-01-19 22:39) [10]

Спасибо огромное!!!! Просто под конец дня плохо соображается.Еще раз спасибо за то что терпеливо обьяснили :)


 
Tolik   (2006-01-19 22:57) [11]

А как можно узнать hThread для определенного потока,если таковых запущено несколько?



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

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

Наверх




Память: 0.49 MB
Время: 0.027 c
6-1130275355
volser
2005-10-26 01:22
2006.02.05
TWebBrowser и события


2-1137793506
newprogrammer
2006-01-21 00:45
2006.02.05
CASE OF


2-1137704176
kizam
2006-01-19 23:56
2006.02.05
такая ошыбка


4-1132933783
badevlad
2005-11-25 18:49
2006.02.05
Получить путь к файлу по его Handle


1-1136370422
race1
2006-01-04 13:27
2006.02.05
Поток и рисование