Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 01.06.2011, 17:02
ZXCCXZ ZXCCXZ вне форума
Прохожий
 
Регистрация: 10.05.2011
Сообщения: 12
Репутация: 10
По умолчанию Создание потока с помощью BeginThread

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

Делаю так:
Код:
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  
Старый 01.06.2011, 17:05
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

через параметр Parameter: Pointer; можно передать все что хочешь. сделай его указателем на record.
__________________
Пишу программы за еду.
__________________
Ответить с цитированием
  #3  
Старый 01.06.2011, 17:07
ZXCCXZ ZXCCXZ вне форума
Прохожий
 
Регистрация: 10.05.2011
Сообщения: 12
Репутация: 10
По умолчанию

Цитата:
Сообщение от NumLock
через параметр Parameter: Pointer; можно передать все что хочешь. сделай его указателем на record.
Пробовал уже так, при передаче Pointer(МояПеременная) выдаёт ошибку
Ответить с цитированием
  #4  
Старый 01.06.2011, 17:10
ZXCCXZ ZXCCXZ вне форума
Прохожий
 
Регистрация: 10.05.2011
Сообщения: 12
Репутация: 10
По умолчанию

А именно пробовал так:

Код:
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  
Старый 01.06.2011, 19:56
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

Код:
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  
Старый 02.06.2011, 00:42
ZXCCXZ ZXCCXZ вне форума
Прохожий
 
Регистрация: 10.05.2011
Сообщения: 12
Репутация: 10
По умолчанию

Однако есть проблема. Каждый раз при вызове функции передаются разные параметры. У вас переменная r объявлена глобальной и получается при одновременном выполнении нескольких экземпляров функции - они все используют одну переменную r. Мне нужно чтобы каждый раз функция запускалась в новом потоке с новыми параметрами (например как я писал Random(5) ).

Пробовал сделать переменную r локальной для процедуры клика на кнопке(procedure TForm1.Button1Click(Sender: TObject), однако в результате при многократном нажатии Button1 - программа вылетает с ошибками AccesViolation.
Ответить с цитированием
  #7  
Старый 02.06.2011, 08:43
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

ну не проблема:
Код:
unit Unit1;

interface

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

type
  PMethodLavrovoi = ^MethodLavrovoi;
  MethodLavrovoi = record
    h: THandle;
    n: Integer;
    i: Integer;
    s: ShortString;
    d: TDateTime;
  end;

  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    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;

implementation

{$R *.dfm}

function ThreadProc(Parameter: PMethodLavrovoi): Integer;
begin
  Sleep(Parameter^.i);
  Parameter^.s:='MethodLavrovoi='+IntToStr(Parameter^.i);
  Parameter^.d:=Parameter^.d-Parameter^.i;
  PostMessage(Parameter^.h, WM_USER+$1001, WPARAM(Parameter), 0);
  Result:=0;
  EndThread(Result);
end;

{ TForm1 }

procedure TForm1.WMUSER(var Msg: TMessage);
var
  p: PMethodLavrovoi;
begin
  Msg.Result:=0;
  p:=PMethodLavrovoi(Msg.WParam);
  Memo1.Lines.Add(IntToStr(p^.n)+'  '+p^.s+'  '+DateTimeToStr(p^.d));
  FreeMemory(p);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  i: Integer;
  p: PMethodLavrovoi;
begin
  for i:=1 to 9 do
  begin
    p:=GetMemory(SizeOf(MethodLavrovoi));
    p^.h:=Handle;
    p^.n:=i;
    p^.i:=(Random(9)+1)*10;
    p^.s:='';
    p^.d:=Now;
    FHandle:=BeginThread(nil, 0, @ThreadProc, p, 0, FThreadID);
  end;
end;

initialization
  Randomize;

end.

CloseHandle(FHandle); для всех потоков сам куда-нить воткнешь, я забыл про них совсем)))
Вложения
Тип файла: rar MethodLavrovoi.rar (2.1 Кбайт, 8 просмотров)
__________________
Пишу программы за еду.
__________________

Последний раз редактировалось NumLock, 02.06.2011 в 08:47.
Ответить с цитированием
Этот пользователь сказал Спасибо NumLock за это полезное сообщение:
harbor (05.05.2013)
  #8  
Старый 02.06.2011, 08:59
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,029
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Я вот не понимаю, а чем стандартный TThrad не годится. По сути он делает все тоже самое. но предоставляет некоторый дополнительный сервис, не сильно перегружающий отдельный поток, но дающий простые способы для выполнения часто применяемых действий (синхронизация, автоматическое закрытие хэндлов и т.д).
А Винда вообще не любит очень много потоков, так что в их кол-ве ты не сильно выиграешь, отказавшись от TThread. Вообще, рекомендую задуматься о пуле потоков.
Ответить с цитированием
  #9  
Старый 02.06.2011, 09:07
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
Радость

lmikle, надеюсь последнее примечание ко мне не относится, я всего лишь следую теме аватара "Создание потока с помощью BeginThread"?
__________________
Пишу программы за еду.
__________________
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 11:45.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter