Показать сообщение отдельно
Старый 08.11.2010, 13:36 #20 (permalink)
Аватар для Aksey
Aksey Aksey вне форума
Популярный
 
Регистрация: 10.03.2010
Сообщений: 50
Aksey is an unknown quantity at this point
Aksey Aksey вне форума
Популярный
Аватар для Aksey
 
Регистрация: 10.03.2010
Сообщений: 50
Aksey is an unknown quantity at this point
По умолчанию

Нужно вычислить число Пи через сумму ряда Лейбница. Задается число потоков, точность вычисления. Нужно, чтобы каждый поток вычислял частичную сумму ряда. например, 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.
Aksey вне форума   Ответить с цитированием