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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Free And Nil Thread 
V
    Опции темы
Ak47black
  Дата 15.10.2007, 18:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Здравствуйте.
Столкнулся с проблемой.
Хочу из потока вызвать процедуру в главном потоке которая-бы разрушала-бы этот поток и приравнивала к переменной nil.
Например вот такой код
Form
Код

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    procedure TestProc;
  end;

var
  Form1: TForm1;
  TestThread: TTestThread;

implementation

{$R *.dfm}

procedure TForm1.TestProc;
begin
  FreeAndNil(TestThread);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  TestThread:= TTestThread.Create(False);
end;

end.

Thread
Код

unit Unit2;

interface

uses
  Classes;

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

implementation

uses
  Unit1;

procedure TTestThread.Execute;
begin
  Synchronize(Form1.TestProc);
end;

end.


Зависает.
Пробовал и через Terminate всякие сделать но без успешно.
Поток при Synchronize я как понял блокируется, а каким путем его можно разблокировать?
Подскажите пожалуйста, что тут можно сделать?  smile 
Я хочу это сделать так-как мне нужно чтобы после завершения, переменная от потока была nil.
PM MAIL   Вверх
aktuba
Дата 15.10.2007, 19:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Смышленный
***


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

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



В конце потока отправляй сообщение главному потоку, т.е.:

Form
Код

unit Unit1;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Unit2;
type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    procedure TestProc(var Msg: TMessage); message WM_DESTRTHREAD;
  end;
var
  Form1: TForm1;
  TestThread: TTestThread;
implementation
{$R *.dfm}
procedure TForm1.procedure TestProc(var Msg: TMessage);
begin
  FreeAndNil(TestThread);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
  TestThread:= TTestThread.Create(True);
  TestThread.FHandle := Handle;
  TestThread.Resume;
end;
end.


Thread
Код

unit Unit2;
interface
uses
  Classes;
type
  TTestThread = class(TThread)
  private
    { Private declarations }
  protected
    procedure Execute; override;
  public
    FHandle: THandle;
  end;
implementation
uses
  Unit1;
procedure TTestThread.Execute;
begin
  // тут действия
  PostMessage(FHandle, WM_DESTRTHREAD, 0, 0);
end;
end.



--------------------
user posted image
PM MAIL WWW Skype   Вверх
MetalFan
Дата 15.10.2007, 20:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Synchronize усыпляет поток до окончания выполнения синхро-функции, а а главный поток, выполняя ее, сам засыпает, ибо ждет освобождения потока.


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
MetalFan
Дата 15.10.2007, 22:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(MetalFan @  15.10.2007,  20:03 Найти цитируемый пост)
у тебя классический дэдлок получается) 

Alexeis, извини) это автору топика было адресовано

Добавлено @ 22:12
Цитата(Alexeis @  15.10.2007,  19:37 Найти цитируемый пост)
Из главного потока вызывается метод Terminate, в результате чего переменной Terminated присваивается True. Дальше из основного потока вызываем  метод потока WaitFor и блокируемся до завершения этого потока. После этого смело делаем FreeAndNil как для любого объекта.

имхо можно сразу вызвать FreeAndNil из осн.потока.
в любом случае потоку будет сказано terminate, и будет WaitFor) см. TThread.Destroy

Это сообщение отредактировал(а) MetalFan - 15.10.2007, 22:14


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
EvilsInterrupt
Дата 16.10.2007, 14:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

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



Ak47black, Я непонял, почему так надо вам!
Как правило, поток выполняет какое-либо действие и свой результат отдает другому потоку, а сам ожидает новых данных. Либо может завершиться. Я думаю вам надо координально пересмотреть свою задачу, тогда не надо будет вызвать процедуру в главном потоке или посылать виндовое сообщение. Я догадываюсь о возможном решении, но я бы хотел знать побольше о задаче. Напиши вкратце ;)
PM MAIL WWW ICQ Jabber   Вверх
Ak47black
Дата 16.10.2007, 14:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Я как понял со всего что было сказано выше, что тут один есть нормальный способ, для того что я хочу сделать, это послать сообщение?
EvilsInterrupt, в данном случае мне нужно просто освободить правильно поток и присвоить к переменной потока nil.
Первое можно сделать при FreeOnTerminate = true
А второе я вижу пока или сообщением или в поток передать ссылку на переменную и при OnDestoy присвоить nil.

Добавлено @ 14:15
Ладно я еше посмотрю, может точно тут смогу чтото переделать.  smile 

Это сообщение отредактировал(а) Ak47black - 16.10.2007, 14:15
PM MAIL   Вверх
EvilsInterrupt
Дата 16.10.2007, 14:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

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



Ak47black, Я бы сделал так:
1. Создал дополнительный поток таким, чтобы после завершения потоковой ф-ции, он сам себя убил
2. В потоковой ф-ции я бы задал вечный цикл по выполнению чего либо
3. Условием из вечного цикла задал булеву переменную, которая бы устанавливалась либо главным потоком, либо другим потоком и означала бы что "конец вычислений".
PM MAIL WWW ICQ Jabber   Вверх
MetalFan
Дата 16.10.2007, 15:13 (ссылка) |    (голосов:3) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(EvilsInterrupt @  16.10.2007,  14:37 Найти цитируемый пост)
Условием из вечного цикла задал булеву переменную,

а terminated на что? ))


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
aktuba
Дата 16.10.2007, 15:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Смышленный
***


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

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



Цитата(Ak47black @  16.10.2007,  15:05 Найти цитируемый пост)
в поток передать ссылку на переменную и при OnDestoy присвоить nil.


А зачем  такие сложности? Чем сообщение не нравиться?


Цитата(EvilsInterrupt @  16.10.2007,  15:37 Найти цитируемый пост)
Я бы сделал так:
1. Создал дополнительный поток таким, чтобы после завершения потоковой ф-ции, он сам себя убил
2. В потоковой ф-ции я бы задал вечный цикл по выполнению чего либо
3. Условием из вечного цикла задал булеву переменную, которая бы устанавливалась либо главным потоком, либо другим потоком и означала бы что "конец вычислений". 


Так можно делать только при условии, что главному потоку не нужны результаты работы дополнительного потока... Ну а насчет Terminated уже Metalfan сказал.


--------------------
user posted image
PM MAIL WWW Skype   Вверх
Alix
Дата 16.10.2007, 15:47 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


L45
**


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

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



А зачем вообще сообщения? Сделайте onThreadTerminated, где и напишите TestThread := nil а при запуске потока просто не забудь сделать TestThread.onTerminated := onThreadTerminated;


--------------------
Знание только тогда знание, когда оно приобретено усилиями своей мысли, а не памятью (с) Л. Толстой
High tech. Low live. (с) Gardner Dozois
PM MAIL ICQ Skype   Вверх
MetalFan
Дата 16.10.2007, 15:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Alix, как вариант сойдет. но тут есть ньанс - обработчик выполняется в контексте главного потока.
это хорошо, если управлением потоками занимается главный поток, а если нет?


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
Alix
Дата 16.10.2007, 16:00 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


L45
**


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

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



Цитата(MetalFan @  16.10.2007,  16:51 Найти цитируемый пост)
это хорошо, если управлением потоками занимается главный поток, а если нет? 

предлагаю строго по запросу  smile 
Цитата(Ak47black @  15.10.2007,  19:17 Найти цитируемый пост)
Хочу из потока вызвать процедуру в главном потоке которая-бы разрушала-бы этот поток и приравнивала к переменной nil.




--------------------
Знание только тогда знание, когда оно приобретено усилиями своей мысли, а не памятью (с) Л. Толстой
High tech. Low live. (с) Gardner Dozois
PM MAIL ICQ Skype   Вверх
Alexeis
Дата 16.10.2007, 16:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

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



  А если есть несколько экземпляров потоков данного класса, то делать несколько обработчиков для каждого?


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
EvilsInterrupt
Дата 16.10.2007, 16:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

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



Цитата

Так можно делать только при условии, что главному потоку не нужны результаты работы дополнительного потока... Ну а насчет Terminated уже Metalfan сказал.

Меня недавно уважаемый SAP (Петрович) так хорошо пнул, что я до сих пор в ужасе, как я раньше делал ! ;)))

А пнул он одной мыслью, что главный поток занимается только и только интерфейсом спользователем, а вот всю рутинную работу отдает своим помошникам, вспомагательным. Есно дело он может у каждого из них спросить: "Занят ли ты?", "А сколько тебе работать осталось?" и т.п.
Поэтому я бы предложил автору задать работу с ГУИ в главном потоке и в нем же создать помошника(ов) в который(ые) уместил бы код по основной ф-циональности проги, т.е. ее бизнес логику. ;) Таким образом юзер видит что прога не висит, т.к. ее рутинные действия делает помошник(и) главного потока и следовательно не торомозят! И заодно видит как идет процесс, т.к. главный поток может спросить  о том как много сделал(и) помошник(и)!

Т.е. модель из жизни, руководитель видит своих подчиненных, подбирает каждому задание, отдает каждому че делать и время от времени справляется о ходе работы. Если подченный долго возится, он вправе спросить почему он так долго возится и в случае чего
разрешить прекратить работу.
Но то что автор говорит, это похоже на то, что подчиненный сам говорит шефу: "Мля, мне надоело и я щас заканчиваю делать твое задание!" ;)

Это сообщение отредактировал(а) EvilsInterrupt - 16.10.2007, 16:40
PM MAIL WWW ICQ Jabber   Вверх
Alix
Дата 16.10.2007, 16:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


L45
**


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

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



Цитата(Alexeis @  16.10.2007,  17:30 Найти цитируемый пост)
А если есть несколько экземпляров потоков данного класса, то делать несколько обработчиков для каждого? 

Код

  TSomeThread = class(TThread)
  private
    ...
    FMyIndex  : integer;
  public
    property myIndex : integer read FMyIndex write FMyIndex;
  ...
  end;
...
var
  someThreads : array of TSomeThread;
...
procedure TForm1.onThreadTerminated(Sender: TObject);
begin
  someThreads[(sender as TSomeThread).myIndex] := nil;
end;
...
      // somewhere
      for i := 0 to length(someThreads)-1 do
        if not Assigned(someThreads[i]) then begin
          someThreads[i] := TSomeThread.create(true);
          with someThreads[i] do begin
            OnTerminate     := onThreadTerminated;
            freeOnTerminate := true;
            myIndex := i;
            ... // other params
            resume;
            break;
          end; 
        end;
...


Это сообщение отредактировал(а) Alix - 16.10.2007, 16:42


--------------------
Знание только тогда знание, когда оно приобретено усилиями своей мысли, а не памятью (с) Л. Толстой
High tech. Low live. (с) Gardner Dozois
PM MAIL ICQ Skype   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

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

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

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

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


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

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


 




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


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

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