|
|
Регистрация | << Правила форума >> | 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
|
||||
|
||||
Блин, а теги где???
По теме: что и где не работает? Тестируй на здоровье сам, а если нужна помощь, говори конкретнее... На первый взгляд вроде всё так... Оставайтесь хорошими людьми... VK id2634397, ds [at] phoenix [dot] dj |
#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
|
||||
|
||||
Вот, кстати неплохая ссылка о семафорах
А если там пощелкать то и вообще про потоки и синхронизацию неплохо написано. |