 |
Популярный
|
|
Регистрация: 10.03.2010
Сообщений: 50
|
|
Популярный
Регистрация: 10.03.2010
Сообщений: 50
|
Нужно вычислить число Пи через сумму ряда Лейбница. Задается число потоков, точность вычисления. Нужно, чтобы каждый поток вычислял частичную сумму ряда. например, 1-ый поток вычисляет сумму ряда с 1-го по 1000 член ряда, 2-ой - с 1001-го по 2000 и т.д. затем результаты всех потоков суммируются.
В принципе, я знаю, как это все делать. Программа зависает при вызове функии WaitForMultipleObjects, когда ждем завершения всех потоков.
Вот исходник главного модуля на Delphi
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Math;
type
TForm1 = class(TForm)
Edit1: TEdit;
Edit2: TEdit;
Label1: TLabel;
Label2: TLabel;
ScrollBox1: TScrollBox;
Memo1: TMemo;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
type PThreadData = ^TThreadData;
TThreadData = record
NumberOfElem : longint;
index : integer;
end;
var CurrPiValue : extended;
epsilon : extended;
ThreadNum : integer;
FLock : TRTLCriticalSection;
n : longint;
hHeap, ThreadId : DWORD;
hThreads : array of integer;//TWOHandleArray;
i:integer;
CreateTime, ExitTime, KernelTime, UserTime : TFileTime;
SysTime : TSystemTime;
PiArray : array of extended;
function ComputePi(Param: Pointer): integer;
var j:integer;
Curr: extended;
ThrThread : TThreadData;
begin
ThrThread:=PThreadData(Param)^;
inc(ThrThread.index);
Curr:=0;
for j:=((ThrThread.index-1)*ThrThread.NumberOfElem+1) to (ThrThread.index*ThrThread.NumberOfElem) do
Curr:=Curr+(Power(-1, j)*4)/(2*j+1);
EnterCriticalSection(FLock);
PiArray[ThrThread.index-1]:=Curr;
LeaveCriticalSection(FLock);
EndThread(0);
end;
procedure TForm1.Button1Click(Sender: TObject);
var ThreadData : PThreadData;
begin
CurrPiValue:=0;
epsilon := StrToFloat(Edit1.Text);
ThreadNum := StrToInt(Edit2.Text);
SetLength(PiArray, ThreadNum);
SetLength(hThreads, ThreadNum);
n:=round(abs(ceil (2/(epsilon)-0.5))/ThreadNum);
InitializeCriticalSection(FLock);
hHeap := GetProcessHeap;
ThreadData:=HeapAlloc(hHeap, 0, SizeOf(TThreadData));
if GetLastError <> 0 then Exit;
ZeroMemory(ThreadData, sizeof(TThreadData));
ThreadData^.NumberOfElem := n;
for i:=0 to ThreadNum-1 do
begin
ThreadData^.index:=i;
//ComputePi(ThreadData);
hThreads[i] := BeginThread(nil, 0, @ComputePi, PThreadData(ThreadData), 0, ThreadId);
//WaitForSingleObject(hThreads[i],INFINITE);
//GetThreadTimes(hThreads[i], CreateTime, ExitTime, KernelTime, UserTime);
//FileTimeToSystemTime(UserTime,SysTime);
//Memo1.Lines.Add('A?aiy iioiea '+IntToStr(i)+' '+IntToStr(SysTime.wMilliseconds));
end;
WaitForMultipleObjects(ThreadNum, @hThreads, TRUE, INFINITE);
for i:=0 to ThreadNum-1 do
CurrPiValue:=CurrPiValue+PiArray[i];
Memo1.Lines.Add(FloatToStr(CurrPiValue+4)); //i?eaaaeyai 4, o.e. n?eoaai n 2-ai ?eaia, a 1-ue ?aaai 4
for i:=0 to ThreadNum-1 do
CloseHandle(hThreads[i]);
//HeapFree(hHeap, 0, ThreadData);
DeleteCriticalSection(FLock);
end;
end.
__________________
Taedium Vitae
Последний раз редактировалось Aksey; 08.11.2010 в 17:41.
|