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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Не работает простейшая прога с потоками... :( 
V
    Опции темы
iPlay
Дата 8.10.2010, 21:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Собственно не работает простейшая прога, не пойму почему???
Код

unit unit1;

interface

uses
windows, messages, sysutils, variants, classes, graphics, controls, forms, dialogs, stdctrls;

type
  tform1 = class(tform)
  memo1: tmemo;
  button1: tbutton;
procedure button1click(sender: tobject);
private
{ private declarations }
public
{ public declarations }
end;

  tnew = class(tthread)
  private
    s: string;
    procedure addstr;
    protected
    procedure execute; override;
  end;

var
  form1: tform1;
  new1, new2: tnew;

implementation

{$r *.dfm}

procedure tform1.button1click(sender: tobject);
begin
  new1 := tnew.create(true);
  new1.freeonterminate := true;
  new1.s := '1 thread';
  new1.priority := tplowest;
  new2 := tnew.create(true);
  new2.freeonterminate := true;
  new2.s := '2 thread';
  new2.priority := tptimecritical;
  new1.resume;
  new2.resume;
end;

{ tnew }
procedure tnew.addstr;
begin
  form1.memo1.lines.add(s);
  sleep(2);
  form1.memo1.lines.add(s);
  sleep(2);
  form1.memo1.lines.add(s);
  sleep(2);
  form1.memo1.lines.add(s);
  sleep(2);
  form1.memo1.lines.add(s);
end;

procedure tnew.execute;
begin
  synchronize(addstr); // Вызов метода с синхронизацией
  //addstr; // Вызов метода без синхронизации
end;

end.

PM MAIL   Вверх
iPlay
Дата 8.10.2010, 22:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Народ, реально уже голову разбил  smile  В чем трабл может быть? smile 
PM MAIL   Вверх
~FoX~
Дата 9.10.2010, 08:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


НЕ рыжий!!!
****


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

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



iPlay, А что не работает то? 

Это сообщение отредактировал(а) ~FoX~ - 9.10.2010, 08:09


--------------------
user posted image
…множественность никогда не следует полагать без необходимости…
PM MAIL WWW ICQ Jabber   Вверх
Dom
Дата 9.10.2010, 14:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



И как предполагается он должен работать? Поскольку смысла код по большому счету не имеет.
PM MAIL   Вверх
xkor
Дата 9.10.2010, 23:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



iPlay, и юзать Sleep в основном потоке оконного приложения не хорошо)
смею предположить что вы хотите чтоб ваш код был таким:
Код

unit unit1;
interface
uses
windows, messages, sysutils, variants, classes, graphics, controls, forms, dialogs, stdctrls;
type
  tform1 = class(tform)
  memo1: tmemo;
  button1: tbutton;
procedure button1click(sender: tobject);
private
{ private declarations }
public
{ public declarations }
end;
  tnew = class(tthread)
  private
    s: string;
    procedure addstr;
    protected
    procedure execute; override;
  end;
var
  form1: tform1;
  new1, new2: tnew;
implementation
{$r *.dfm}
procedure tform1.button1click(sender: tobject);
begin
  new1 := tnew.create(true);
  new1.freeonterminate := true;
  new1.s := '1 thread';
  new1.priority := tplowest;
  new2 := tnew.create(true);
  new2.freeonterminate := true;
  new2.s := '2 thread';
  new2.priority := tptimecritical;
  new1.resume;
  new2.resume;
end;
{ tnew }
procedure tnew.addstr;
begin
  form1.memo1.lines.add(s);
end;
procedure tnew.execute;
begin
  synchronize(addstr); // Вызов метода с синхронизацией
  sleep(2);
  synchronize(addstr); // Вызов метода с синхронизацией
  sleep(2);
  synchronize(addstr); // Вызов метода с синхронизацией
  sleep(2);
  synchronize(addstr); // Вызов метода с синхронизацией
  sleep(2);
  synchronize(addstr); // Вызов метода с синхронизацией
  //addstr; // Вызов метода без синхронизации
end;
end.

и что вы слабо представляете что такое и для чего надо использовать synchronize...

Это сообщение отредактировал(а) xkor - 9.10.2010, 23:26
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
iPlay
Дата 10.10.2010, 22:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Проблема была в том что потоки, просто не выполнялись!!!! Код взял в инете smile)) Кстати да слабо представляю что такое и для чего надо использовать synchronize... как с WinAPI работать отлично представляю, а тут как-то интересно smile))

Еще вопрос можно, потоки заработали, интересно как синхронизировать с помощью критических секций? 
Есть код первый поток должен сгенить число, а второй возьмет ну например синус от него.
Код

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls,syncobjs, Math;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    Edit2: TEdit;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  tnew = class(tthread)
 // procedure my;
  private
    tmp:real;
    name:string;
    protected
    procedure execute; override;
  end;

var
  Form1: TForm1;
  cs,cs2: tcriticalsection;
  new1, new2: tnew;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  new1 := tnew.create(true);
  new1.freeonterminate := true;
  new1.priority := tptimecritical;
  new1.name:='1st thread';


  new2 := tnew.create(true);
  new2.freeonterminate := true;
  new2.priority:=tplowest;
  new2.name:='2st thread';

  new1.resume;
  new2.resume;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  // Ñîçäàåì ÊÑ
  cs := tcriticalsection.create;
  cs2:= tcriticalsection.create;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
 // Óäàëÿåì
  cs.free;
  cs2.Free;
end;
   
procedure tnew.execute;
begin

     randomize;
  Form1.Memo1.Lines.Add(name);
   cs.enter;
      tmp:=random(20);
      Form1.Edit1.Text:=FloatToStr(tmp);
   cs.leave;
   sleep(2000);
   cs2.enter;
      tmp:=sin(tmp);
      Form1.Edit2.Text:=FloatToStr(tmp);
   cs2.leave;
end;
end.



Это сообщение отредактировал(а) iPlay - 10.10.2010, 22:06
PM MAIL   Вверх
Dom
Дата 11.10.2010, 01:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Пару подсказок:
1. Нельзя обращаться к VCL компонентам из кода потока.
2. Если очень хочется, то можно, но только через процедуру Synchronize, которая выполняется в контексте главного потока.

А для ознакомления с потоками тут есть отличная статья - http://forum.vingrad.ru/forum/topic-60076.html
PM MAIL   Вверх
iPlay
Дата 11.10.2010, 08:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



То есть насколько я понял, прошлый код с критическими секциями
Код

unit Unit1;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls,syncobjs, Math;
type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    Edit2: TEdit;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
  tnew = class(tthread)
 // procedure my;
  private
    tmp:real;
    name:string;
    protected
    procedure execute; override;
  end;
var
  Form1: TForm1;
  cs,cs2: tcriticalsection;
  new1, new2: tnew;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
  new1 := tnew.create(true);
  new1.freeonterminate := true;
  new1.priority := tptimecritical;
  new1.name:='1st thread';
  new2 := tnew.create(true);
  new2.freeonterminate := true;
  new2.priority:=tplowest;
  new2.name:='2st thread';
  new1.resume;
  new2.resume;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
  cs := tcriticalsection.create;
  cs2:= tcriticalsection.create;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
  cs.free;
  cs2.Free;
end;
   
procedure tnew.execute;
begin
     randomize;
  Form1.Memo1.Lines.Add(name);
   cs.enter;
      tmp:=random(20);
      Form1.Edit1.Text:=FloatToStr(tmp);
   cs.leave;
   sleep(2000);
   cs2.enter;
      tmp:=sin(tmp);
      Form1.Edit2.Text:=FloatToStr(tmp);
   cs2.leave;
end;
end.

 неважно, какой поток захватит выполнение, поскольку я ограничил критическими секциями ресурс то они полюбому параллельно не выполнятся. Тогда вопрос, можно дополнять критические секции функцией synchronize();????
PM MAIL   Вверх
cat512
Дата 11.10.2010, 09:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(Dom @ 11.10.2010,  01:21)
Пару подсказок:
1. Нельзя обращаться к VCL компонентам из кода потока.
2. Если очень хочется, то можно, но только через процедуру Synchronize, которая выполняется в контексте главного потока.

А для ознакомления с потоками тут есть отличная статья - http://forum.vingrad.ru/forum/topic-60076.html

Не вводите людей в заблуждение!
А кто запрещает???
Код

// выполняется в контексте первого потока
proc1
begin
  Lock;
  try
    Memo1.Lines. add(('somtfing');
  finally
    unlock;
  end;
end;
// выполняется в контексте второго потока
proc2
begin
  Lock;
  try
    Memo1.Lines. add(('somtfing');
  finally
    unlock;
  end;

end;

Vcl-компонент? - ДА
Обращение из кода потоков? - ДА
Очень хочется? - да smile, но не использую synchronize
Цитата

Тогда вопрос, можно дополнять критические секции функцией synchronize();????

Не надо ничего дополнять, используй либо секции либо synchronize. 



Это сообщение отредактировал(а) cat512 - 11.10.2010, 09:22
PM MAIL   Вверх
iPlay
Дата 11.10.2010, 09:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



То есть правильная реализация прошлой программы такова???
Код

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls,Math,SyncObjs;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Edit2: TEdit;
    Button1: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  tnew = class(tthread)
  procedure first;
  procedure second;
  private
    tmp:real;
    name:string;
    protected
    procedure execute; override;
  end;

var
  Form1: TForm1;
  cs,cs2: tcriticalsection;
  new1, new2: tnew;
implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
new1 := tnew.create(true);
  new1.freeonterminate := true;
  new1.priority := tptimecritical;
  new1.name:='1st thread';

  new2 := tnew.create(true);
  new2.freeonterminate := true;
  new2.priority:=tplowest;
  new2.name:='2st thread';

  new1.resume;
  new2.resume;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  cs := tcriticalsection.create;
  cs2:= tcriticalsection.create;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  cs.free;
  cs2.free;
end;

procedure tnew.first;
begin
   randomize;
   form1.memo1.lines.add(name);
   cs.enter;
      tmp:=random(20);
      form1.edit1.text:=floattostr(tmp);
   cs.leave;
end;

procedure tnew.second;
begin
  cs2.enter;
     tmp:=sin(tmp);
     form1.edit2.text:=floattostr(tmp);
  cs2.leave;
end;

procedure tnew.execute;
begin
  first;
  sleep(2000);
  second;
end;
end.

Просто я когда вот так сделал,  все равно захватывает 2й поток иногда первее??? Чето я не пойму smile  Можете подсказать конкретно на этом примере?
PM MAIL   Вверх
iPlay
Дата 11.10.2010, 10:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Собственно просто, когда я работал с WinAPI там все четко, создавался поток в него передавался адрес функции которая обрабатывает данный поток, а реализацию писал в этой функции.

Тут как-то интересно, функция tthread_name.execute выполняется и первым и вторым потоком, не могу понять что если мне нужно чтобы один поток выполнял одно а другой другое...??? Я просто скорее всего чего то недопонимаю.... А пример с критическими секциями, как раз таков что нужно чтобы один поток делал одно а другой другое.
PM MAIL   Вверх
RomanEEP
Дата 11.10.2010, 11:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(cat512 @  11.10.2010,  09:16 Найти цитируемый пост)
Не вводите людей в заблуждение!А кто запрещает???

Запрещает архитектура VCL, которая однопоточна. Например во время добавления строки в мемо может пересоздаться Handle memo из-за изменения системных настроек или действий в основном потоке. Про другие компоненты я вообще молчу. Результат работы такой предсказуем... правда не для конечного пользователя.
PM MAIL   Вверх
cat512
Дата 11.10.2010, 11:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата

Можете подсказать конкретно на этом примере?

Я же показал пример выше! В методах Lock, Unlock - надо просто вызывать Enter Leave - соответственно. В чём проблема?
Зачем 2 критические секции????????????????????????????????????????????????????????????????????
Толку от них как от козла молока! 
Цитата

Собственно просто, когда я работал с WinAPI там все четко, создавался поток в него передавался адрес функции которая обрабатывает данный поток, а реализацию писал в этой функции

С классом TThread тоже самое. Функцию. которую ты передавал в winapi, в классе TThread наз. Execute
Цитата

Тут как-то интересно, функция tthread_name.execute выполняется и первым и вторым потоком, не могу понять что если мне нужно чтобы один поток выполнял одно а другой другое...??? Я просто скорее всего чего то недопонимаю.... А пример с критическими секциями, как раз таков что нужно чтобы один поток делал одно а другой другое.

Создай либо два разных класса, либо 2 разных функции, и в зависимости от параметра вызывай их в Execute

Добавлено @ 11:24
2RomanEEP
Цитата

Например во время добавления строки в мемо может пересоздаться Handle memo из-за изменения системных настроек или действий в основном потоке

Хай себе меняется! Каким образом мне это навредит, если я использую механизмы синхронизации???
Если "нож" острый, это совсем не значит, что его нельзя использовать осторожно.


Это сообщение отредактировал(а) cat512 - 11.10.2010, 12:16
PM MAIL   Вверх
iPlay
Дата 11.10.2010, 11:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Я написал, две отдельных функции, а в зависимости от какого параметра их запускать?
PM MAIL   Вверх
cat512
Дата 11.10.2010, 11:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(iPlay @ 11.10.2010,  11:25)
Я написал, две отдельных функции, а в зависимости от какого параметра их запускать?

Который собственно, ты будешь определять, в зависимости от того что надо. (Либо в конструкторе либо через переменную)
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

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

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

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

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


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

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


 




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


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

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