![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
#1
|
|||
|
|||
|
Помогите люди... короче дано задание: Расчет значений и вывод в Memo в одном потоке. Построение графика в другом потоке. Функция – y=a*e^(b*x)* cos(sin(a*x+b)) (x∈[-∞,+∞], a, b – const). Для синхронизации использовать семафор. Я вроде написал, но хочу узнать правильно или нет, а может можно было и по другому.
Код:
unit UPotok;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, TeEngine, Series, TeeProcs, Chart;
type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
Label1: TLabel;
Image1: TImage;
Edit1: TEdit;
Label2: TLabel;
Edit2: TEdit;
Label3: TLabel;
Edit3: TEdit;
Label4: TLabel;
Edit4: TEdit;
Label5: TLabel;
Label6: TLabel;
Chart1: TChart;
Series1: TLineSeries;
procedure Edit4KeyPress(Sender: TObject; var Key: Char);
procedure Edit3KeyPress(Sender: TObject; var Key: Char);
procedure Edit2KeyPress(Sender: TObject; var Key: Char);
procedure Edit1KeyPress(Sender: TObject; var Key: Char);
procedure Button1Click(Sender: TObject);
private
procedure PotokDone(Sender: TObject);
end;
KosPotok = Class (TThread)
protected
procedure Execute; override;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
var
a,b:real;
size,x1,x2,x,Flag:integer;
FlagEnter:integer = 0;
y: array of Real;
hSem: THandle = 0;
procedure RaschetFunction;
begin
if (Length(Form1.Edit1.Text)=0) or (Length(Form1.Edit2.Text)=0)
or (Length(Form1.Edit3.Text)=0) or (Length(Form1.Edit4.Text)=0)then
begin
ShowMessage('Введите все необходимые данные');
exit;
end;
Flag:=1;
x1:=StrToInt(Form1.Edit3.Text);
x:=x1;
x2:=StrToInt(Form1.Edit4.Text);
a:=StrToFloat(Form1.Edit1.Text);
b:=StrToFloat(Form1.Edit2.Text);
if x1>x2 then
begin
ShowMessage('Укажите правильный диапозон(X2>X1)');
exit;
end;
Form1.Button1.Enabled:=false;
Form1.Series1.Clear;
Form1.Memo1.Clear;
size:=abs(x2-x1)+1;
SetLength(y,size);
hSem := CreateSemaphore(nil,1,1,nil);
KosPotok.Create(False);
KosPotok.Create(False);
end;
// Обрабатывается первый поток
procedure KosPotok.Execute;
var
i: Integer;
Rec: DWORD;
begin
OnTerminate:= Form1.PotokDone; // событие при завершение потока
Rec:=WaitForSingleObject(hSem,INFINITE); // уменьшаем значение счетчика семофора на 1
if Rec = WAIT_OBJECT_0 then
begin
for i := 0 to size-1 do
begin
y[i]:= a*Exp(b*x)*cos(Sin(a*x+b));
Form1.Memo1.Lines.Add('При х='+IntToStr(x) +' y=' +FloatToStr(y[i]));
Inc(x);
Sleep(100);
end;
end;
end;
// Обрабатывается второй поток (только после завершение первого)
procedure TForm1.PotokDone(Sender: TObject);
var
i:integer;
begin
Inc(Flag);
if Flag=2 then
begin
x:=x1;
for i :=0 to size-1 do
begin
Series1.AddXY(x, y[i], '', clBlue);
inc(x);
end;
Finalize(y);
CloseHandle(hSem);
Form1.Button1.Enabled:=true;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
RaschetFunction;
end;
// Обработка вводимых данных
procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
case Key of
'0' .. '9', #8 : ;
#13: RaschetFunction;
',' :
begin
if Key = ',' then Key:=',';
if (Pos(',',Form1.Edit1.Text) <> 0) then Key:= Chr(0);
end;
'-' :
begin
if Key = '-' then Key:='-';
if Length(Form1.Edit1.Text) <> 0 then Key:= Chr(0);
end;
else
Key := Chr(0);
end;
end;
procedure TForm1.Edit2KeyPress(Sender: TObject; var Key: Char);
begin
case Key of
'0' .. '9', #8 : ;
#13: RaschetFunction;
',' :
begin
if Key = ',' then Key:=',';
if Pos(',',Form1.Edit2.Text) <> 0 then Key:= Chr(0);
end;
'-' :
begin
if Key = '-' then Key:='-';
if Length(Form1.Edit2.Text) <> 0 then Key:= Chr(0);
end;
else
Key := Chr(0);
end;
end;
procedure TForm1.Edit3KeyPress(Sender: TObject; var Key: Char);
begin
case Key of
'0' .. '9', #8 : ;
#13: RaschetFunction;
'-' :
begin
if Key = '-' then Key:='-';
if Length(Form1.Edit3.Text) <> 0 then Key:= Chr(0);
end;
else
Key := Chr(0);
end;
end;
procedure TForm1.Edit4KeyPress(Sender: TObject; var Key: Char);
begin
case Key of
'0' .. '9', #8 : ;
#13: RaschetFunction;
'-' :
begin
if Key = '-' then Key:='-';
if Length(Form1.Edit4.Text) <> 0 then Key:= Chr(0);
end;
else
Key := Chr(0);
end;
end;
end.lmikle: Да, где теги??? |
|
#2
|
||||
|
||||
|
Блин, а теги где???
По теме: что и где не работает? Тестируй на здоровье сам, а если нужна помощь, говори конкретнее... На первый взгляд вроде всё так... |
|
#3
|
||||
|
||||
|
Не совсем так.
Алгоритм должен быть приблизительно такой: Создается семафор. Создается 2 потока ( разных ). Поток №1: - в цикле ( for i := 0 to size-1 do ): - захватывает семафор - рассчитывает очередную точку - записывает ее в массив y - отпускает семафор - заносит данные точки в мемо ( для работы с визуальными компонентами надо использовать Synchronize ) - в начало цикла Поток №2: - в цикле - захватывает семафор - проверяет если появилась новая расчитаная точка считывает ее - отпускает семафор - наносит новую точку ( точки ) на график ( не забывая Synchronize) повторяет цикл пока не определит что больше точек не будет ( или что все точки нанесены ) |
|
#4
|
|||
|
|||
|
Цитата:
мне надо сделать так чтобы график строился во втором потоке после того как только завершится первый, а неодновременно... и если не сложно то объсни как захватывать и отпускать поток |
|
#5
|
|||
|
|||
|
Цитата:
блин....... работать может любая прога... но не так как требуется... у меня все расчитыватся и выводит правильно... я спросил правильно ли я выполнил задачу, что именно так надо было написать??? |
|
#6
|
||||
|
||||
|
Цитата:
Тоже второй потокю Код:
if WaitForSingleObject(hSem,INFINITE) = WAIT_OBJECT_0 then
begin
try
//расчеты и в мемо
finally
ReleaseSemaphore(hSem,1);
end;
end; |
|
#7
|
||||
|
||||
|
Вот, кстати неплохая ссылка о семафорах
А если там пощелкать то и вообще про потоки и синхронизацию неплохо написано. |