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

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

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль

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

Ответ
 
Опции темы Поиск в этой теме
Старый 24.11.2011, 19:18   #1
fredwriter
Форумчанин
 
Регистрация: 06.10.2009
Сообщений: 121
По умолчанию Как определить закончил ли работу поток?

Здравствуйте, как определить закончил ли работу поток?
Код:
 begin
    Potok1 := ParallelObj.Create(true);
    Potok2 := Potok2Obj.Create(true);
    Potok1.Priority := tpNormal;
    Potok2.Priority := tpNormal;
    Potok1.Resume;
    Potok2.Resume;
  end;
Ищущий да обрящет
fredwriter вне форума Ответить с цитированием
Старый 24.11.2011, 23:23   #2
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

Код:
if (WAIT_OBJECT_0 = WaitForSingleObject(Potok1.Handle, 1)) then ... // Potok1 завершился
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."
veniside вне форума Ответить с цитированием
Старый 01.12.2011, 08:56   #3
fredwriter
Форумчанин
 
Регистрация: 06.10.2009
Сообщений: 121
По умолчанию

то есть, для того, чтобы код выполнился только по завершении двух потоков можно его оформить так:
Код:
begin
  // запуск потоков
  Potok1 := ParallelObj.Create(true);
  Potok2 := Potok2Obj.Create(true);
  Potok1.Priority := tpNormal;
  Potok2.Priority := tpNormal;
  Potok1.Resume;
  Potok2.Resume;
  // ниже код, который должен выполниться через мгновение после завершения двух 
  // потоков, то есть, это значит, что данные получаемые из потоков уже есть и их 
  // можно обрабатывать, это должно произойти незамедлительно после завершения
  // двух потоков.
  if (WAIT_OBJECT_0 = WaitForSingleObject(Potok1.Handle, 1))
  and (WAIT_OBJECT_0 = WaitForSingleObject(Potok2.Handle, 1)) then
  begin
    ....;
    ....;
  end;

end;
Ищущий да обрящет

Последний раз редактировалось fredwriter; 01.12.2011 в 08:59.
fredwriter вне форума Ответить с цитированием
Старый 01.12.2011, 10:43   #4
fredwriter
Форумчанин
 
Регистрация: 06.10.2009
Сообщений: 121
По умолчанию

Может быть, то, что я спрашиваю, сейчас не актуально и есть в инете куча примеров работы с потоками, но конкретного примера с нормальными объяснениями того, что мне нужно нигде нет. Помогите пожалуйста.
Ищущий да обрящет
fredwriter вне форума Ответить с цитированием
Старый 01.12.2011, 10:58   #5
Rififi
Старожил
 
Регистрация: 19.08.2009
Сообщений: 2,119
По умолчанию

fredwriter

сначала сюда, потом - сюда.
Rififi вне форума Ответить с цитированием
Старый 01.12.2011, 11:48   #6
fredwriter
Форумчанин
 
Регистрация: 06.10.2009
Сообщений: 121
По умолчанию

Почитал про функцию WaitForSingleObjects, она заставляет поток ждать пока освободится объект. Какой объект занят потоком когда он выполняется? Например если в потоках происходит перемножение двух массивов M1 и M2: array of array of integer. В каждом по половине массива. Мне нужно самому создать объекты и занять ими потоки? Не понимаю концепции.
Ищущий да обрящет
fredwriter вне форума Ответить с цитированием
Старый 01.12.2011, 12:44   #7
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

для начала постарайтесь верно формулировать задачу.

Цитата:
как определить закончил ли работу поток
Цитата:
чтобы код выполнился только по завершении двух потоков
эти задачи принципиально отличаются. Для решения второй, код будет такой:

Код:
handles: array[0..1] of THandle;

handles[0] := Potok1.Handle;
handles[1] := Potok2.Handle;
if (WAIT_OBJECT_0 = WaitForMultipleObjects(2, @handles, true, timeout)) then .. // оба завершились
Отличие не только в количестве. Обратите внимание на timeout, этот параметр задаёт, сколько вы готовы ждать окончания работы потоков (в мс). Если готовы ждать бесконечно, задайте INFINITE.

Код:
она заставляет поток ждать пока освободится объект. Какой объект занят потоком когда он выполняется
Для хэндлов потоков WaitForХХХ() работает просто: хендл считается установленным (signaled), когда поток завершился. Никаких других объектов там нет.
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."
veniside вне форума Ответить с цитированием
Старый 01.12.2011, 13:38   #8
fredwriter
Форумчанин
 
Регистрация: 06.10.2009
Сообщений: 121
По умолчанию

Огромнейшее спасибо, veniside,
Цитата:
Если готовы ждать бесконечно, задайте INFINITE.
Зачем же мне ждать бесконечно, я точно знаю, что потоки завершатся.
А если они еще не завершились, то он просто пропустит ветку if then что ли? Мне нужно обязательно дождаться завершения, а только потом продолжить.
Ищущий да обрящет
fredwriter вне форума Ответить с цитированием
Старый 01.12.2011, 17:37   #9
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

timeout — это верхний потолок ожидания. Если оба потока завершатся через 1 мс, то и WaitFor() вернётся через 1 мс, даже если был задан INFINITE.

Но вот если из-за какой-то ошибки один из потоков не завершится, при INFINITE вы будете ждать вечно.

Цитата:
ОСНОВНОЕ РАЗЛИЧИЕ МЕЖДУ ПРЕДМЕТОМ, КОТОРЫЙ МОЖЕТ ИСПОРТИТЬСЯ, И ПРЕДМЕТОМ, КОТОРЫЙ ИСПОРТИТЬСЯ НЕ МОЖЕТ, СОСТОИТ В ТОМ, ЧТО ПРЕДМЕТ, КОТОРЫЙ НЕ МОЖЕТ ИСПОРТИТЬСЯ, НЕВОЗМОЖНО ПОЧИНИТЬ. ЕСЛИ ОН ВСЕ-ТАКИ ИСПОРТИЛСЯ.
Поэтому я обычно указываю какой-то reasonable timeout, например, 20 секунд (зависит от задачи). Если по истечении этого времени потоки не завершились, значит, что-то пошло не так, и их надо прибивать.
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."
veniside вне форума Ответить с цитированием
Старый 01.12.2011, 19:27   #10
fredwriter
Форумчанин
 
Регистрация: 06.10.2009
Сообщений: 121
По умолчанию

Цитата:
Но вот если из-за какой-то ошибки один из потоков не завершится, при INFINITE вы будете ждать вечно.
Не может быть никакой ошибки, в потоках просто матрицы перемножаются, которые заранее инициализированы в основном потоке, если они не инициализированы, то потоки не запустятся, поэтому мне timeout не нужен. В принципе, на всякий случай можно и воспользоваться, но я не знаю, почему вдруг у меня могут не выполниться потоки. Я не это хотел узнать а следующее: WaitFor() застявляет ждать один поток пока не освободиться объект занятый другим потоком, но условие
Код:
if WAIT_OBJECT_0 = WaitFor(...) then
как я понял лишь проверяет завершены ли потоки, если да, то программа зайдет на эту ветку if then, если нет, то пропустит её и продолжится.
Может я не правильно понял?
Ищущий да обрящет

Последний раз редактировалось fredwriter; 01.12.2011 в 19:30.
fredwriter вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как защитить поток coNsept Общие вопросы C/C++ 2 24.09.2011 20:17
Поток. Не получается создать поток. Выдает ошибки при запуске bigory Общие вопросы по Java, Java SE, Kotlin 3 23.09.2010 00:40
Как создать поток record222 Помощь студентам 1 07.04.2010 01:09
Как отменить поток RIO Общие вопросы Delphi 11 12.10.2009 00:29
Как остановить поток? Никки Win Api 3 06.12.2007 22:04