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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> узнать о завершении потока 
:(
    Опции темы
sunnmas
Дата 3.8.2009, 14:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Есть поток 1, который запускает множество потоков 2 и только и делает, что следит за состоянием этих, запущенных им потоков 2. Эти потоки 2 завершают свою работу и разлагаются)). Таких потоков 2 может быть ограниченное число (определяется пользователем). 
Вопрос: как узнать что потоки 2 уже заканчивают свою работу, чтобы запускать новые?

Код

Поток 1:
цикл
  Если потоков мало то
    создать нужн. кол-во потоков
    запоминаем на них ссылки в списке
    фриОнТерминатед = тру
    запустить потоки
  конецесли

  Здесь нужно вычислить сколько потоков из списка завершились, 
  т.е. узнать на сколько потоков стало меньше. Как?
  
конеццикла

PM MAIL   Вверх
Romikgy
Дата 3.8.2009, 15:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

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



OnTerminate


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
sunnmas
Дата 3.8.2009, 15:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Поток 1 не главный поток не ВЦЛЬ. ОнТерминате выполняется в главном потоке. Так не нужно
PM MAIL   Вверх
Romikgy
Дата 3.8.2009, 17:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

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



через что создаются потоки тогда ? код покажи 


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
sunnmas
Дата 3.8.2009, 17:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Код

unit TaskManager;

interface
uses Classes, Messages, RegThread, WordSet;

type TThreadTask = (Reg,Confirm,GetCategory,AddNew);

type TTaskManager = class(TThread)
  private
    RegThrLst: TList;

    NumRegThread: byte;

    HandleSet: TWordSet;
  public
    constructor Create(CreateSuspended: Boolean);
    destructor Destroy;
    procedure Execute; override;
end;
implementation

uses Main;

{ TTaskManager }

constructor TTaskManager.Create(CreateSuspended: Boolean);
begin
  inherited Create(CreateSuspended);
  NumRegThread:=0;

  RegThrLst:=TList.Create;

  HandleSet:=TWordSet.Create(20);
end;

destructor TTaskManager.Destroy;
begin
  RegThrLst.Destroy;
end;

procedure TTaskManager.Execute;
var RegThrd: TRegThread;
    i: integer;
begin
  inherited;
  while not Terminated do
  begin
    if NumRegThread<MainForm.RegNmThr then
    begin
      RegThrd:=TRegThread.Create(true,HandleSet.MinAbsentInSet);
      HandleSet.Add(HandleSet.MinAbsentInSet);
      RegThrLst.Add(RegThrd);
      NumRegThread:=NumRegThread+1;
      RegThrd.FreeOnTerminate:=true;
      RegThrd.Resume;
    end;
    for i:=0 to RegThrLst.Count-1 do
    begin
[size=10] [color=crimson]     if TRegThread(RegThrLst.Items[i]).Suspended then
      begin
        HandleSet.Sub(TRegThread(RegThrLst.Items[i]).ThreadHandle);
        TRegThread(RegThrLst.Items[i]).Destroy;
        RegThrLst.Delete(i);
        NumRegThread:=NumRegThread-1;[/color][/size]
      end;
    end;
  end;
end;

end.


картинка во вложении. Цветом выделен блок, которым я проверяю окончание работы потоков2

Это сообщение отредактировал(а) sunnmas - 3.8.2009, 17:48

Присоединённый файл ( Кол-во скачиваний: 9 )
Присоединённый файл  __________.JPG 36,89 Kb
PM MAIL   Вверх
Alexeis
Дата 3.8.2009, 19:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


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

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



  У каждого Thread есть функция waitfor, которая будет ожидать завершения потока. Ее можно вызвать из любого потока.


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

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

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


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


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

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



sunnmas, ой жесть какая... может стоит сначала книжки умные почитать прежде, чем чушь городить?

Добавлено через 6 минут и 56 секунд
1. деструктор у наследника TThread не перекрыт. вызов метода Destroy предка соотв. не происходит.
2. Зато перекрыт метод Execute, что нафиг не нужно)
3. в делфи не принято вызывать напрямую Destroy, для этого есть метод Free.
4. второй цикл в Execute бредовый... словишь AV или List Index out of bound легко.
5. зачем NumRegThread, если есть RegThrLst.Сount ?
....
N. лучше иногда книжки почитать, чем что-то писать...


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


Шустрый
*


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

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



Согласимся с тем что олень, но не перестанем бицца)

Отступим назад. Вот пример приложения очень простого. Откуда там беруться глюки? Просвятите пожалуйста

Присоединённый файл ( Кол-во скачиваний: 3 )
Присоединённый файл  Test.rar 174,25 Kb
PM MAIL   Вверх
atomAltera
Дата 4.8.2009, 03:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



можно и 
Код

postMessage(mainThread.handle, WM_USER+666, subThread.handle, 0)
 в конце каждого суб потока юзать... 
PM MAIL ICQ Skype GTalk   Вверх
MetalFan
Дата 4.8.2009, 08:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



atomAltera, а нельзя. по крайней мере так. да, синхронизация с пом.сообщений возможна, но только лучше таки книжку почитать, или очень хорошую статью на этом форуме...


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


Амеба
Group Icon


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

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



atomAltera, между последней строчкой потока и окончанием его жизни есть разница. По идее в момент отправки сообщения поток еще жив. Реально узнать о его завершении через хэндл можно вызвав WaitForSingleObject и дождавшись когда винда сама скажет - "да поток завершен, все его ресурсы освобождены". 


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

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

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


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

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



при использовании 


Цитата(sunnmas @  3.8.2009,  16:47 Найти цитируемый пост)
FreeOnTerminate:=true;

могу придложить такой вариант 
Код

 mythread = class(TThread)
  private
    { Private declarations }
    fhnd: Pointer;

  protected
   ...
    destructor Destroy; override;

    public
     procedure setclass( x: Pointer );
  end;

destructor mythread.Destroy;
begin

  inherited;
  if fhnd<>nil then
  TObject(fhnd^):=nil;
end;

procedure mythread.setclass(x: Pointer);
begin
 fhnd:=x;
end;


создание объекта изменится чуть 
Код

t:=mythread.Create(True);
  t.setclass(@t);
t.FreeOnTerminate:=True;
      t.Resume;

и проверка на убит процесс или нет 
Код

if Assigned(t) then

если поток автоубился значит процедуру ассигн он не пройдет ,
smile 
жду критики .....


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
MetalFan
Дата 4.8.2009, 14:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Romikgy
ничего конечно идея, но, имхо, потокоНЕбезопасно...


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


Амеба
Group Icon


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

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



Цитата(MetalFan @  4.8.2009,  13:27 Найти цитируемый пост)
ничего конечно идея, но, имхо, потокоНЕбезопасно...

  Почему же? Операция присвоения атомараная. Только вот негибко и не прозрачно. По моему если тебе важен момент завершения, то зачем делать FreeOnTerminate ? Классическая схема состоит в том чтобы вызвать у потока метод Terminate, который выставляет флаг Terminated в true. Правильный поток должен периодически проверять этот флаг и после установки его в true максимально быстро выйти из основного цикла. Поток вызвавший Terminate сразу же вызывает WaitFor и дожидается смерти потока(короткое время), после чего он может получить все необходимые финальные данные из убитого потока, после чего вызвать ему безопасно free; 
  Если же потоки часто создаются и уничтожаются то это неправильная политика, потому что неэффективная. Ненужный поток легко приостанавливается эвенте, после чего перестает потреблять процессорное время и в нужный момент может сразу же приступить к новой задаче, для этого достаточно будет поставить ему новую задачу (потокобезопасно ведь поток спит на эвенте) переключить эвент в активное состояние и ждать завершения работы, после чего поток можно снова усыпить на эвенте до появления новой задачи. 
  Т.о. вопросы уничтожения потоков появляются только по завершению работы программы один раз. Тут важно завершить связанные потоки их в правильной последовательности.


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

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

гениальность идеи состоит в том, что ее невозможно придумать
PM 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.0864 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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