Модераторы: Snowy, MetalFan, bems, Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Упростить работу с потоком 
:(
    Опции темы
valerchi
Дата 1.3.2011, 01:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 163
Регистрация: 27.5.2008
Где: Геническ

Репутация: нет
Всего: нет



Помогите упростить работу с потоком. Вот в чём суть : запускается программа и сразу запускается второй поток, который считает бесконечный цикл и записывает значение цикла в файл. Потом по нажатию кнопки на форме открывается этот файл, в который записано значение, значение считывается и выводится на экран. Можно ли сделать так, чтобы никаких файлов не было, а значение бралось при нажатии кнопки непосредственно из второго , работающего потока и выводилось на экран? Вот что у меня имеется:
Код

unit potokslch;

interface

uses
  Classes;

type
  potok = class(TThread)
  private
    { Private declarations }
  protected
    procedure Execute; override;
    
  end;

implementation

{ Important: Methods and properties of objects in visual components can only be
  used in a method called using Synchronize, for example,

      Synchronize(UpdateCaption);

  and UpdateCaption could look like,

    procedure potok.UpdateCaption;
    begin
      Form1.Caption := 'Updated in a thread';
    end; }

{ potok }

procedure potok.Execute;
var f:textfile;x:integer; label l;
begin
  { Place thread code here }
begin
x:=0;
repeat

x:=x+1;
if x=53 then x:=1;
l: begin
assignfile(f,'d:\два потока.txt');
{$i-}
rewrite(f);
{$I+}
if IOResult <> 0 then   goto l;
writeln(f,(x));
closefile(f);
end;
until (x=68);
end;
end;

end.
 


И главный поток:
Код

unit Sluchainie_chisla_dva_potoka;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs,potokslch, StdCtrls, Buttons;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    BitBtn1: TBitBtn;
    procedure Button1Click(Sender: TObject);
    procedure BitBtn1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  x:string; Fpotok: potok;
implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
f: TextFile; // файл
label l;
begin
Fpotok := potok.Create(False);
l:
AssignFile(f, 'd:\два потока.txt');
{$i-}
Reset(f); // открыть для чтения
{$I+}
if IOResult <> 0 then    goto l;
begin
readln(f, x); // прочитать строку из файла
CloseFile(f); // закрыть файл
end;
end;
memo1.lines.Add(x);


end;

procedure TForm1.BitBtn1Click(Sender: TObject);
begin

   Fpotok.Terminate;
   Fpotok.Free;

end;

end.

PM MAIL   Вверх
kami
Дата 1.3.2011, 01:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 22
Всего: 72



Код

procedure potok.Execute;
  ...
  ReturnValue:=x;
  .....
end;

...
memo1.lines.Add(IntToStr(FPotok.ReturnValue));


Посмотрите внимательно на метод Button1Click.
Что будет, если нажать на кнопку 2 раза? Правильно, будет создан второй поток, а о созданном при первом нажатии программа просто забудет, а Windows будет помнить. И начнут эти 2 потока бороться за несчастный файл...
Как минимум, там нужно
Код

  if not Assigned(FPotok) then
    FPotok:=potok.Create;


В остальное страшно вникать.

Это сообщение отредактировал(а) kami - 1.3.2011, 01:24
PM MAIL WWW   Вверх
northener
Дата 1.3.2011, 02:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1361
Регистрация: 2.9.2010

Репутация: 12
Всего: 20



Цитата(valerchi @  1.3.2011,  01:02 Найти цитируемый пост)
Помогите упростить работу с потоком. Вот в чём суть : запускается программа и сразу запускается второй поток, который считает бесконечный цикл и записывает значение цикла в файл. Потом по нажатию кнопки на форме открывается этот файл, в который записано значение, значение считывается и выводится на экран. Можно ли сделать так, чтобы никаких файлов не было, а значение бралось при нажатии кнопки непосредственно из второго , работающего потока и выводилось на экран?


Можно.
Но лучше сразу сформулировать задачу, а не вопрос.


--------------------
Но только лошади летают вдохновенно.
Иначе лошади разбились бы мгновенно!
PM MAIL   Вверх
valerchi
Дата 1.3.2011, 12:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 163
Регистрация: 27.5.2008
Где: Геническ

Репутация: нет
Всего: нет



Сделал так, - второй поток запускается, когда активируется форма. Но опять ничего не получается. Вот что получилось:
Код

unit Sluchainie_chisla_dva_potoka;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs,potokslch, StdCtrls, Buttons;
type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    BitBtn1: TBitBtn;
    procedure Button1Click(Sender: TObject);
    procedure BitBtn1Click(Sender: TObject);
    procedure FormActivate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
var
  Form1: TForm1;
  x:string; Fpotok: potok;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin

memo1.lines.Add(x);

end;
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
   Fpotok.Terminate;
   Fpotok.Free;
end;
procedure TForm1.FormActivate(Sender: TObject);
begin
Fpotok := potok.Create(False);
end;

end.

И второй поток:
Код

unit potokslch;

interface

uses
  Classes;

type
  potok = class(TThread)
  private
    { Private declarations }
  protected
    procedure Execute; override;
    
  end;

implementation

{ Important: Methods and properties of objects in visual components can only be
  used in a method called using Synchronize, for example,

      Synchronize(UpdateCaption);

  and UpdateCaption could look like,

    procedure potok.UpdateCaption;
    begin
      Form1.Caption := 'Updated in a thread';
    end; }

{ potok }

procedure potok.Execute;
var x:integer; label l;
begin
  { Place thread code here }
begin
x:=0;
repeat

x:=x+1;
if x=53 then x:=1;
until (x=68);
end;
end;
end.


PM MAIL   Вверх
cat512
Дата 1.3.2011, 13:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 438
Регистрация: 20.3.2007

Репутация: 2
Всего: 15



Самый простой вариант:
Сделай свойство у второго потока, которое будет иниц. в цикле, а в главном потоке считывай это свойство.
PM MAIL   Вверх
valerchi
Дата 1.3.2011, 22:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 163
Регистрация: 27.5.2008
Где: Геническ

Репутация: нет
Всего: нет



Цитата(cat512 @ 1.3.2011,  13:01)
Самый простой вариант:
Сделай свойство у второго потока, которое будет иниц. в цикле, а в главном потоке считывай это свойство.

А как конкретно это сделать?
PM MAIL   Вверх
valerchi
Дата 2.3.2011, 13:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 163
Регистрация: 27.5.2008
Где: Геническ

Репутация: нет
Всего: нет



Цитата(kami @ 1.3.2011,  01:23)
Код

procedure potok.Execute;
  ...
  ReturnValue:=x;
  .....
end;

...
memo1.lines.Add(IntToStr(FPotok.ReturnValue));



Сделал так, а мне высвечивает :  Undeclared identifier: 'ReturnValue'
PM MAIL   Вверх
valerchi
Дата 3.3.2011, 12:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 163
Регистрация: 27.5.2008
Где: Геническ

Репутация: нет
Всего: нет



Неужели ничего нельзя сделать? Как я понимаю, теоретически это должно было выглядеть так: второй поток выполняет бесконечный цикл и заносит значен6ие  "х" в какой - нибудь буфер памяти, а главный поток при нажатии кнопки считывает эту информацию и выдаёт на экран. В моём случае вместо буфера памяти у меня создавался файл, записывался туда результат, а главный поток его считывал. Но это слишком громоздко и неудобно. Может кто знает, как создать такой буфер памяти?
PM MAIL   Вверх
MetalFan
Дата 3.3.2011, 13:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 22
Всего: 128



valerchi, а что мешает перейти от теории к практике?
Не знаете, как выделить буфер в памяти? или что использовать в качестве буфера? как обеспечить "раздельный" доступ к буферу?
Просто вопрос выглядит как "я ничего не знаю, подскажите, что делать".
Перво наперво рекомендую к обязательному прочтению статью Многопоточность - как это делается в Дельфи. Если что-то непонятно после первого прочтения, прочитать еще раз.


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Для новичков"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0499 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.