Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 11.11.2010, 00:25   #1
fredwriter
Форумчанин
 
Регистрация: 06.10.2009
Сообщений: 121
По умолчанию Потоки

Здравствуйте!
Подскажите пожалуйста, как сделать, чтобы выполнялся код четырех процедур одновременно, и каждая процедура выводила в своё поле memo одной формы, какие-то данные. То-есть, четыре процедуры, четыре поля memo, одна форма, одновременный вывод данных каждой процедурой в одно из полей Memo.
Я попробовал использовать потоки, а я подозреваю, что нужно использовать потоки, у меня в двух потоках File→New→Other→ThreadObject две процедуры, которые выводят в два Label'a на главной форме значения переменных обрабатываемых этими потоками. Потоки запускаются одной кнопкой на главной форме, и останавливаются одной кнопкой. При нажатии на кнопку запустить форма зависает. Если один поток убрать, то всё работает.
Вот частичный код Юнита формы:
Код:
unit MainUnit;

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls, ThreadUnit, Thread_Unit_1;

private
    co: TCountObj;
    co1: TCountObj_1;

procedure TForm1.Button1Click(Sender: TObject);
begin
  co := TCountObj.Create(true);
  co.Resume;
  co.Priority := tpLower;
  co1 := TCountObj_1.Create(true);
  co1.Resume;
  co1.Priority := tpLower;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  co.Terminate;
  co1.Terminate;
end;

Ниже частичные коды юнитов потоков:

1 поток

unit ThreadUnit;

implementation
uses
  MainUnit;

private
    index: integer;
    procedure UpdateLabel;

procedure TCountObj.Execute;
begin
  index := 1;
  while index > 0 do
  begin
    Synchronize(UpdateLabel);
    Inc(index);
    if index > 100000 then
      index := 0;
    if terminated then exit;
  end;
end;

procedure TCountObj.UpdateLabel;
begin
  Form1.Label1.Caption := IntToStr(index);
end;

2 поток

unit Thread_Unit_1;

implementation
uses
  MainUnit;

private
    index1: integer;
    Procedure UpdateLabel1;

procedure TCountObj_1.Execute;
begin
  index1 := 1;
  while index1 > 0 do
  begin
    Synchronize(UpdateLabel1);
    Inc(index1);
    if index1 > 100000 then
      index1 := 0;
    if terminated then exit;
  end;
end;


Procedure TCountObj_1.UpdateLabel1;
begin
  Form1.Label2.Caption := IntToStr(Index1);
end;
Ищущий да обрящет
fredwriter вне форума Ответить с цитированием
Старый 11.11.2010, 00:33   #2
mihali4
*
Старожил
 
Регистрация: 22.11.2006
Сообщений: 9,201
По умолчанию

В штатных дельфийских демках есть демка с потоками. Вы ее код разбирали ?
mihali4 вне форума Ответить с цитированием
Старый 11.11.2010, 00:53   #3
fredwriter
Форумчанин
 
Регистрация: 06.10.2009
Сообщений: 121
По умолчанию

нет не разбирал

Получается, что мне не нужно создавать два раза File→New→Other→ThreadObject, а можно в одном описать мои процедуры, но сложновато там как-то, я делал по книге Флёнова, там всё разжевано, но мало, а в демке не разжевано и много.

Если бы кто-нибудь помог, разжевал так сказать...

У нас принято пользоваться кнопочкой "Правка", дабы не плодить посты подряд, друг за другом.
Читаем правила. Рекомендую. Помимо общих правил форума есть и дополнения к ним в каждом разделе...
Уважайте форумчан, и они ответят вам взаимностью...
Модератор
Ищущий да обрящет

Последний раз редактировалось mihali4; 11.11.2010 в 02:54.
fredwriter вне форума Ответить с цитированием
Старый 11.11.2010, 02:17   #4
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

да можно при желании и один класс потока юзать.

а вообще висит потому что не верно выбран метод синхронизации, ибо код выполняемый под Stnchronize выполняется как бы в одном потоке.(главном)
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 11.11.2010, 02:27   #5
Voody
Форумчанин
 
Регистрация: 22.06.2009
Сообщений: 310
По умолчанию

Могу помочь с созданием потока методом класса)
Т.е. в MainUnit дописываем:
Описание классов
Код:
TNewThread1 = class(TThread)
  private
   index:integer;
  protected
    procedure Execute; override;
  public
    procedure UpdateLabel;
    constructor Create(CreateSuspended: Boolean);
  end;

TNewThread2 = class(TThread)
  private
   index1:integer;
  protected
    procedure Execute; override;
  public
    procedure UpdateLabel1;
    constructor Create(CreateSuspended: Boolean);
  end;
Тут же описываем конструкторы:
Код:
constructor TNewThread.1Create(CreateSuspended: Boolean);
begin
  inherited Create(CreateSuspended);
end;

constructor TNewThread2.Create(CreateSuspended: Boolean);
begin
  inherited Create(CreateSuspended);
end;
И коды кнопок будут такими:

Код:
procedure TForm1.Button1Click(Sender: TObject);
begin
 stop1:=false; 
 stop2:=false; 
 TNewThread1.Create(false);
 TNewThread2.Create(false);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  stop1:=true; 
  stop2:=true; // глобальные переменные
end;
Никаких других юнитов не нужно. Тут же пишем коды в потоках:

Код:
procedure TNewThread1.Execute;
begin
 index := 1;
  while index > 0 do
  begin
    Synchronize(UpdateLabel);
    Inc(index);
    if index > 100000 then
      index := 0;
    if stop1 then exit;
  end;
end;

procedure TNewThread2.Execute;
begin
  index1 := 1;
  while index1 > 0 do
  begin
    Synchronize(UpdateLabel1);
    Inc(index1);
    if index1 > 100000 then
      index1 := 0;
    if stop2 then exit;
  end;
end;

procedure TNewThread1.UpdateLabel;
begin
 Form1.Label1.Caption := IntToStr(index);
end;

procedure TNewThread2.UpdateLabel1;
begin
 Form1.Label2.Caption := IntToStr(Index1);
end;
Voody вне форума Ответить с цитированием
Старый 11.11.2010, 05:46   #6
fredwriter
Форумчанин
 
Регистрация: 06.10.2009
Сообщений: 121
По умолчанию

Voody Большое спасибо за помощь

Цитата:
Пепел Феникса
а вообще висит потому что не верно выбран метод синхронизации, ибо код выполняемый под Stnchronize выполняется как бы в одном потоке.(главном)
Подкажите какой метод здесь правильный может быть CheckSynchronize
Ищущий да обрящет
fredwriter вне форума Ответить с цитированием
Старый 11.11.2010, 10:41   #7
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

в данном случае хорошо подходят сообщения.

кстати, Voddy, в вашем случае конструкторы не нужно переделывать.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 11.11.2010, 11:15   #8
fredwriter
Форумчанин
 
Регистрация: 06.10.2009
Сообщений: 121
По умолчанию

Цитата:
Сообщение от Пепел Феникса Посмотреть сообщение
в данном случае хорошо подходят сообщения.
извините, не понял, какие сообщения, я в теме потоков ни какой, поэтому, пожалуйста, можно поподробнее?
Ищущий да обрящет
fredwriter вне форума Ответить с цитированием
Старый 11.11.2010, 11:25   #9
Dеlphi
нажмите + на весах
Пользователь
 
Регистрация: 10.11.2010
Сообщений: 30
По умолчанию

Код:
procedure TCountObj.Execute;
begin
  index := 1;
  while (not terminated) and  (index < 100000) do
  begin
    Synchronize(UpdateLabel);
    Inc(index);
  end;
end;
11:34

Код:
uses                   syncobjs,
 section: tcriticalsection; // глобальная переменная
где ни будь будь вначале до потока:
Код:
section:= tcriticalsection.Create;
Код:
procedure TCountObj.Execute;
begin
  index := 1;
  while (not terminated) and  (index < 100000) do
  begin
section.Enter;
    UpdateLabel;
 section.Leave;
    Inc(index);
  end;
end;
...
потом
Код:
 section.free
У нас принято пользоваться кнопочкой "Правка", дабы не плодить посты подряд, друг за другом.
Читаем правила. Рекомендую. Помимо общих правил форума есть и дополнения к ним в каждом разделе...
Уважайте форумчан, и они ответят вам взаимностью...
Модератор
Если помог нажми на весы

Последний раз редактировалось mihali4; 12.11.2010 в 00:30.
Dеlphi вне форума Ответить с цитированием
Старый 11.11.2010, 11:40   #10
fredwriter
Форумчанин
 
Регистрация: 06.10.2009
Сообщений: 121
По умолчанию

Спасибо Dеlphi
Ищущий да обрящет
fredwriter вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Потоки StudeHt Помощь студентам 1 06.05.2010 16:26
потоки tanek Помощь студентам 6 15.03.2010 21:42
потоки Владимир1988 Помощь студентам 0 08.02.2010 23:12