![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
|
|
#1
|
|||
|
|||
|
Здравствуйте, мне в программе необходимо запускать функцию несколько раз, каждый раз в новом потоке, потоки должны работать одновременно, потоков может быть очень много.
Делаю так: Код:
procedure MyProcedure(a:integer); begin Form1.Memo1.Lines.Add(TimeToStr(Now)+' New thread, a:'+IntToStr(a)); sleep(1000*a); Form1.Memo1.Lines.Add(TimeToStr(Now)+'Thread with a:'+IntToStr(a)+' finished'); ExitThread(0); end; procedure TForm1.Button1Click(Sender: TObject); var dw:Dword; begin BeginThread(nil,0,@MyProcedure,Pointer(Random(5)),0,dw); end; initialization randomize; Всё работает, очень даже хорошо. Вопрос в следующем: как быть с функцией, которой нужно передать 2 или более параметров? Например: MyProcedure(a:integer; b:string; c:TDateTime); Как через BeginThread передать функции 2 или более параметров? Последний раз редактировалось ZXCCXZ, 01.06.2011 в 17:06. |
|
#2
|
||||
|
||||
|
через параметр Parameter: Pointer; можно передать все что хочешь. сделай его указателем на record.
|
|
#3
|
|||
|
|||
|
Цитата:
|
|
#4
|
|||
|
|||
|
А именно пробовал так:
Код:
type
MyP = record
a:integer;
b:string;
c:TDateTime;
end;
...
procedure MyProcedure(mp:MyP);
...
procedure TForm1.Button1Click(Sender: TObject);
var
dw:Dword;
mp:MyP;
begin
mp.a:=Random(5);
mp.b:='123';
mp.c:=Now;
BeginThread(nil,0,@MyProcedure,Pointer(mp),0,dw);
end;Ошибка следующая: [Error] Unit1.pas(50): Invalid typecast Последний раз редактировалось ZXCCXZ, 01.06.2011 в 17:14. |
|
#5
|
||||
|
||||
|
Код:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
PMethodLavrovoi = ^MethodLavrovoi;
MethodLavrovoi = record
h: THandle;
i: Integer;
s: String;
d: TDateTime;
end;
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure WMUSER(var Msg: TMessage); message WM_USER+$1001;
end;
var
Form1: TForm1;
FHandle: THandle;
FThreadID: THandle;
r: MethodLavrovoi;
implementation
{$R *.dfm}
function ThreadProc(Parameter: PMethodLavrovoi): Integer;
var
i: Integer;
begin
Parameter^.s:='MethodLavrovoi';
Parameter^.d:=Parameter^.d-1;
for i:=1 to Parameter^.i do
begin
Windows.Beep(1000, 100);
Sleep(500);
end;
PostMessage(Parameter^.h, WM_USER+$1001, 0, 0);
Result:=0;
EndThread(Result);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
r.h:=Handle;
r.i:=3;
r.s:='';
r.d:=Now;
FHandle:=BeginThread(nil, 0, @ThreadProc, @r, 0, FThreadID);
end;
procedure TForm1.WMUSER(var Msg: TMessage);
begin
ShowMessage(r.s+' '+DateToStr(r.d));
end;
end. |
|
#6
|
|||
|
|||
|
Однако есть проблема. Каждый раз при вызове функции передаются разные параметры. У вас переменная r объявлена глобальной и получается при одновременном выполнении нескольких экземпляров функции - они все используют одну переменную r. Мне нужно чтобы каждый раз функция запускалась в новом потоке с новыми параметрами (например как я писал Random(5) ).
Пробовал сделать переменную r локальной для процедуры клика на кнопке(procedure TForm1.Button1Click(Sender: TObject) , однако в результате при многократном нажатии Button1 - программа вылетает с ошибками AccesViolation. |