Форум: "Начинающим";
Текущий архив: 2014.03.02;
Скачать: [xml.tar.bz2];
ВнизКак распределить функции по потокам Найти похожие ветки
← →
Valdis (2013-05-07 20:18) [0]Добрый день/вечер.
Я никогда не применял мультитрединг в Дельфи. У меня возник вопрос:
Возможно ли в одной программе несколько функций разбить по потокам/нитям, например:function f1(a,b:integer):real;
var i:integer;
begin
for i:=1 to 10000 do
result:=(a+2*b)+i/2 end;
function f2(a,b:integer):real;
var i:integer;
begin
for i:=1 to 2000 do
result:=(a/b)*i end;
Как сделать чтобы для каждой функции f1 и f2 был предоставлен персональный поток, и они высчитывались параллельно и конечный результат S:real выжидал бы каждую из функций.S:=f1(strtoint(edit1.text),strtoint(edit2.text))+f2(strtoint(edit3.text),strtoint(edit4.text))
Если возможно по подробнее и на данном примере. Заранее спасибо и пожалуйста.
p.s. Ответы типа читай хелпы или гуглируй не предлогать.
← →
MBo © (2013-05-07 20:26) [1]Начни с примера в Demos\Threads
← →
Медвежонок Пятачок © (2013-05-08 05:05) [2]Как сделать чтобы для каждой функции f1 и f2 был предоставлен персональный поток, и они высчитывались параллельно и конечный результат S:real выжидал бы каждую из функций.
Result := f1() + f2();
персональные потоки для ф1 и ф2 в твоей постановке задачи не нужны.
← →
Inovet © (2013-05-08 06:11) [3]> [2] Медвежонок Пятачок © (08.05.13 05:05)
Видимо, имелся в виду основной поток и по одному на функцию.
← →
Медвежонок Пятачок © (2013-05-08 06:23) [4]Интересно зачем?
ну создаем мы два вычисляющих потока.
но по условиям нам надо дождаться пока они оба вычислят свои функции.
как будем ждать?
1. крутить цикл ожидания в основном потоке
2. нагородим третий ожидающий поток и будем крутить цикл в нем (а в основном будем ждать третий)
3. наприсовываем сюда семафоров-шмемафоров и будем синхронизироваться по ним.
4. построим распределенную облачную систему.....
5. создадим новое сколково для решения проблемы автора
← →
brother © (2013-05-08 06:35) [5]> Если возможно по подробнее и на данном примере. Заранее
> спасибо и пожалуйста.
>
> p.s. Ответы типа читай хелпы или гуглируй не предлогать.
улыбнуло.
потоки для обоих функций в данном случае не нужны...
← →
Inovet © (2013-05-08 06:42) [6]> [4] Медвежонок Пятачок © (08.05.13 06:23)
> 3. наприсовываем сюда семафоров-шмемафоров и будем синхронизироваться по ним.
Циклы-то со сколковыми нафига. Если функции именно показанные автором, так потоки тогда не нужны из практических соображений.
← →
MBo © (2013-05-08 09:21) [7]Многопоточное вычисление неведомой фигни:
(потоки по старой традиции, в свежих Дельфях для таких простых задач есть новые средства)
"Ожидание" здесь упрощенное.
type
TCalcThread = class(TThread)
private
FA, FB: Integer;
FResult: Double;
protected
procedure Execute; override;
public
constructor Create(A, B: Integer);
function AResult: Double;
function A: Integer;
function B: Integer;
end;
TForm1 = class(TForm)
Button1: TButton;
ListBox1: TListBox;
procedure Button1Click(Sender: TObject);
private
StartedCount, FinishedCount: Integer;
Sum: Double;
{ Private declarations }
public
{ Public declarations }
procedure CalcTerminated(Sender: TObject);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{ TCalcThread }
function TCalcThread.A: Integer;
begin
Result := FA;
end;
function TCalcThread.AResult: Double;
begin
Result := FResult;
end;
function TCalcThread.B: Integer;
begin
Result := FB;
end;
constructor TCalcThread.Create(A, B: Integer);
begin
inherited Create(True);
FA := A;
FB := B;
Resume;
end;
procedure TCalcThread.Execute;
var
i : Integer;
begin
FResult := 0;
for i := FA to FB do
FResult := Fresult + Sin(i) * Ln(i + 1);
end;
{ TForm1 }
procedure TForm1.Button1Click(Sender: TObject);
var
i, A, B: integer;
begin
Randomize;
StartedCount := 4;
FinishedCount := 0;
A := 0;
for i := 1 to StartedCount do begin
B := A + 1000000 + Random(10000000);
with TCalcThread.Create(A, B) do begin
FreeOnTerminate := True;
OnTerminate := CalcTerminated;
end;
A := B + 1;
end;
end;
procedure TForm1.CalcTerminated(Sender: TObject);
var
A, B: Integer;
begin
Sum := Sum + TCalcThread(Sender).AResult;
A := TCalcThread(Sender).A;
B := TCalcThread(Sender).B;
Inc(FinishedCount);
ListBox1.Items.Add(Format("Thread %d range [%d, %d] finished Sum = %f",
[FinishedCount, A, B, Sum]));
if FinishedCount = StartedCount then
ListBox1.Items.Add("Alles kaput");
end;
← →
"Добрый Сок" (2013-05-08 11:15) [8]>> Если возможно по подробнее и на данном примере.
не, копипаста не будет :)
совсем просто:
type
TCalc = class(TThread)
protected
procedure Execute; override;
public
A: Integer;
R: integer;
end;
TForm1 = class(TForm)
btn1: TButton;
procedure btn1Click(Sender: TObject);
private { Private declarations }
public { Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.btn1Click(Sender: TObject);
var
C1, C2: TCalc;
T: Cardinal;
begin
C1 := TCalc.Create(true);
C2 := TCalc.Create(true);
C1.A := 7;
C2.A := 6;
C1.Resume;
C2.Resume;
T := GetTickCount;
repeat // wait
Application.ProcessMessages; //or message to notify about complete calc, but need think how difference
until (C1.A = -maxint) and (C2.A = -maxint);
ShowMessageFmt("%d + %d = %d ; but %d",[C1.R, C2.R, C1.R+C2.R, Round((GetTickCount - T)/1000)]);
FreeAndNil(C1);
FreeAndNil(C2);
end;
{ TCalc }
procedure TCalc.Execute;
var
i: Integer;
begin
inherited;
for i := 0 to A-1 do
begin
R := R + 1;
Sleep(1000); // immitation long calc
end;
//SendMessage(Form1.Handle, WM_USER, 0, 0); //or message to notify about complete calc, but need think how difference
A := -maxint; //or message
end;
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2014.03.02;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.002 c