Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Программа и интерфейс
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 24.03.2010, 23:57
koszh2007 koszh2007 вне форума
Прохожий
 
Регистрация: 24.03.2010
Сообщения: 11
Репутация: 10
По умолчанию Синхронизация потоков при помощи симафоров

Помогите люди... короче дано задание: Расчет значений и вывод в 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  
Старый 25.03.2010, 00:08
Аватар для PhoeniX
PhoeniX PhoeniX вне форума
Always hardcore!
 
Регистрация: 04.03.2009
Адрес: СПб
Сообщения: 3,239
Версия Delphi: GCC/FPC/FASM
Репутация: 62149
По умолчанию

Блин, а теги где???
По теме: что и где не работает? Тестируй на здоровье сам, а если нужна помощь, говори конкретнее...
На первый взгляд вроде всё так...
__________________
Оставайтесь хорошими людьми...
VK id2634397, ds [at] phoenix [dot] dj
Ответить с цитированием
  #3  
Старый 25.03.2010, 09:10
Аватар для s0Creator
s0Creator s0Creator вне форума
Местный
 
Регистрация: 20.02.2008
Адрес: Московская область
Сообщения: 420
Репутация: 884
По умолчанию

Не совсем так.
Алгоритм должен быть приблизительно такой:
Создается семафор.
Создается 2 потока ( разных ).
Поток №1:
- в цикле ( for i := 0 to size-1 do ):
- захватывает семафор
- рассчитывает очередную точку
- записывает ее в массив y
- отпускает семафор
- заносит данные точки в мемо ( для работы с визуальными компонентами надо использовать Synchronize )
- в начало цикла

Поток №2:
- в цикле
- захватывает семафор
- проверяет если появилась новая расчитаная точка
считывает ее
- отпускает семафор
- наносит новую точку ( точки ) на график ( не забывая Synchronize)
повторяет цикл пока не определит что больше точек не будет ( или что все точки нанесены )
Ответить с цитированием
  #4  
Старый 26.03.2010, 12:41
koszh2007 koszh2007 вне форума
Прохожий
 
Регистрация: 24.03.2010
Сообщения: 11
Репутация: 10
По умолчанию

Цитата:
Сообщение от s0Creator
Не совсем так.
Алгоритм должен быть приблизительно такой:
Создается семафор.
Создается 2 потока ( разных ).
Поток №1:
- в цикле ( for i := 0 to size-1 do ):
- захватывает семафор
- рассчитывает очередную точку
- записывает ее в массив y
- отпускает семафор
- заносит данные точки в мемо ( для работы с визуальными компонентами надо использовать Synchronize )
- в начало цикла

Поток №2:
- в цикле
- захватывает семафор
- проверяет если появилась новая расчитаная точка
считывает ее
- отпускает семафор
- наносит новую точку ( точки ) на график ( не забывая Synchronize)
повторяет цикл пока не определит что больше точек не будет ( или что все точки нанесены )

мне надо сделать так чтобы график строился во втором потоке после того как только завершится первый, а неодновременно... и если не сложно то объсни как захватывать и отпускать поток
Ответить с цитированием
  #5  
Старый 26.03.2010, 16:46
koszh2007 koszh2007 вне форума
Прохожий
 
Регистрация: 24.03.2010
Сообщения: 11
Репутация: 10
По умолчанию

Цитата:
Сообщение от DJ PhoeniX
Блин, а теги где???
По теме: что и где не работает? Тестируй на здоровье сам, а если нужна помощь, говори конкретнее...
На первый взгляд вроде всё так...

блин....... работать может любая прога... но не так как требуется... у меня все расчитыватся и выводит правильно... я спросил правильно ли я выполнил задачу, что именно так надо было написать???
Ответить с цитированием
  #6  
Старый 27.03.2010, 08:23
Аватар для s0Creator
s0Creator s0Creator вне форума
Местный
 
Регистрация: 20.02.2008
Адрес: Московская область
Сообщения: 420
Репутация: 884
По умолчанию

Цитата:
Сообщение от koszh2007
мне надо сделать так чтобы график строился во втором потоке после того как только завершится первый, а неодновременно... и если не сложно то объсни как захватывать и отпускать поток
Все практически также, только первый поток захватывает симафор в самом начале и отпускает в самой конце Execute/
Тоже второй потокю
Код:
 if WaitForSingleObject(hSem,INFINITE) = WAIT_OBJECT_0 then
 begin
  try
    //расчеты и в мемо
  finally
    ReleaseSemaphore(hSem,1);
  end;

 end;
Ответить с цитированием
  #7  
Старый 27.03.2010, 08:41
Аватар для s0Creator
s0Creator s0Creator вне форума
Местный
 
Регистрация: 20.02.2008
Адрес: Московская область
Сообщения: 420
Репутация: 884
По умолчанию

Вот, кстати неплохая ссылка о семафорах
А если там пощелкать то и вообще про потоки и синхронизацию неплохо написано.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 11:50.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter