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

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

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

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

Ответ
 
Опции темы Поиск в этой теме
Старый 23.08.2009, 21:03   #1
Voody
Форумчанин
 
Регистрация: 22.06.2009
Сообщений: 310
По умолчанию Ожидание завершения потоков

Структура программы такая:

Код:
{первая часть}

{запуск потоков}

{вторая часть}
Нужно, чтобы после запуска потоков программа ждала их завершения, а потом уже выполнялась вторая часть.
Как это лучше реализовать?
Voody вне форума Ответить с цитированием
Старый 23.08.2009, 21:17   #2
Daramant
Форумчанин
 
Регистрация: 06.01.2009
Сообщений: 340
По умолчанию

С данной задачей вполне справятся семафоры.
Тебе нужна идея или пример привести?
Истинный успех – это то, что Вы сделали в сравнении с тем, что могли бы сделать.
Никогда не бойся делать то, что ты не умеешь. Помни, ковчег был построен любителем. Профессионалы построили "Титаник".
Daramant вне форума Ответить с цитированием
Старый 23.08.2009, 21:33   #3
Voody
Форумчанин
 
Регистрация: 22.06.2009
Сообщений: 310
По умолчанию

лучше пример, если можно)))
причем важно, чтобы программа не зависала, пока ждала завершения потоков
Voody вне форума Ответить с цитированием
Старый 23.08.2009, 22:10   #4
Daramant
Форумчанин
 
Регистрация: 06.01.2009
Сообщений: 340
По умолчанию

Пример я сейчас набросаю.
Цитата:
причем важно, чтобы программа не зависала, пока ждала завершения потоков
Насколько не зависала?
Достаточно прогрессбара или необходимо, чтобы была полная работоспособность (окна не подвисали)?

Можешь немного рассказать о решаемой задаче, чтобы было яснее.
Чтобы ничего не подвисало, можно ожидание вынести также в отдельный поток, тогда будет то, что тебе нужно.
Истинный успех – это то, что Вы сделали в сравнении с тем, что могли бы сделать.
Никогда не бойся делать то, что ты не умеешь. Помни, ковчег был построен любителем. Профессионалы построили "Титаник".
Daramant вне форума Ответить с цитированием
Старый 23.08.2009, 22:25   #5
Voody
Форумчанин
 
Регистрация: 22.06.2009
Сообщений: 310
По умолчанию

Я, кстати, делал так (не ругать))):
Код:
{первая часть}

{запуск потоков}
 Next:=0;
 while Next<>2 do  Application.ProcessMessages;

{вторая часть}
т.е. Next считает количество завершенных потоков, и когда их становится два, то продолжаем дальше программу. Всё работало, но почему-то буквально вчера заметил, что происходит так: заходит в потоки, потоки вызывают процедуру и на этом программа просто стопорится (ничего не происходит; только продолжает выполняться Application.ProcessMessages).
Хотя если пишу while true do Application.ProcessMessages; то ничего не стопорится. Но естественно, что такой вариант не подходит))

Цитата:
Насколько не зависала?
полная работоспособность. Ибо потоки обновляют компоненты (Label) на форме, и пользователь должен видеть обновление статистики.
Проблема возникла как раз из-за того, что вдруг перестало работать моё "очевидное" решение. А так оно меня вполне устраивало))

Последний раз редактировалось Voody; 23.08.2009 в 22:27.
Voody вне форума Ответить с цитированием
Старый 23.08.2009, 23:15   #6
Daramant
Форумчанин
 
Регистрация: 06.01.2009
Сообщений: 340
По умолчанию

Вот пример.
Если что не так, пиши, доработаю.

Цитата:
Next:=0;
while Next<>2 do Application.ProcessMessages;
Чтобы такой вариант работал, необходимо в потоках обращаться к Next через кретическую секцию, а то складывается ситуация когда несколько потоков пытаются писать в одну переменную и выходит косяк.
Но, конечно лучше через ожидание событий.
Вложения
Тип файла: rar ThreadManager.rar (3.6 Кб, 133 просмотров)
Истинный успех – это то, что Вы сделали в сравнении с тем, что могли бы сделать.
Никогда не бойся делать то, что ты не умеешь. Помни, ковчег был построен любителем. Профессионалы построили "Титаник".

Последний раз редактировалось Daramant; 23.08.2009 в 23:19.
Daramant вне форума Ответить с цитированием
Старый 24.08.2009, 00:27   #7
Voody
Форумчанин
 
Регистрация: 22.06.2009
Сообщений: 310
По умолчанию

Цитата:
Сообщение от Daramant Посмотреть сообщение
Вот пример.
Если что не так, пиши, доработаю.
Спасибо большое. Сделал так:
N - количество потоков, задает пользователь
Код:
Semaphore := CreateSemaphore(nil, 0, N, nil);
for i:=1 to N do
  CheckThread.Create(false);
WaitForSingleObject(Semaphore, INFINITE);
{продолжаем код}
А в конце потока поставил ReleaseSemaphore(Semaphore, 1, nil);

Первая проблема: программа виснет, если стоит INFINITE.
Но... вторая проблема: вместо INFINITE поставил 1000 (как я понял, это интервал проверки семафора). Всё равно продолжает выполнятся вторая часть кода, не ожидая завершения потоков(((


Цитата:
Сообщение от Daramant Посмотреть сообщение
Чтобы такой вариант работал, необходимо в потоках обращаться к Next через кретическую секцию, а то складывается ситуация когда несколько потоков пытаются писать в одну переменную и выходит косяк.
Но, конечно лучше через ожидание событий.
В том, то и дело, что программа раньше работала, а сейчас нет, и даже не доходит до изменения Next, просто стоит((
Voody вне форума Ответить с цитированием
Старый 24.08.2009, 00:54   #8
Daramant
Форумчанин
 
Регистрация: 06.01.2009
Сообщений: 340
По умолчанию

WaitForSingleObject(). Ожидает пока не освободится семафор.
Если стоит, например 1000, то будет секундное ожидание и начнется выполнение операторов после WaitForSingleObject().
Тебе необходимо INFINITE, ждать пока точно все не отработают.
Цитата:
Первая проблема: программа виснет, если стоит INFINITE.
Я менял количество потоков, у меня все работает, может проблема в коде, который выполняется в потоках.
Класс CheckThread сам писал или это потомок от класса tthread из Delphi?
Переменная Semaphore точно глобальная?
Истинный успех – это то, что Вы сделали в сравнении с тем, что могли бы сделать.
Никогда не бойся делать то, что ты не умеешь. Помни, ковчег был построен любителем. Профессионалы построили "Титаник".
Daramant вне форума Ответить с цитированием
Старый 24.08.2009, 14:55   #9
Voody
Форумчанин
 
Регистрация: 22.06.2009
Сообщений: 310
По умолчанию

Цитата:
Сообщение от Daramant Посмотреть сообщение
Я менял количество потоков, у меня все работает, может проблема в коде, который выполняется в потоках.
Класс CheckThread сам писал или это потомок от класса tthread из Delphi?
Переменная Semaphore точно глобальная?
Код:
CheckThread = class(TThread)
...
implementation
var
Semaphore: THandle;
как у вас в программе((( но моя программа виснет.
Не могли бы вы привести более наглядный пример, например: нажимается кнопка - запускаются потоки - изменяется Label - завершаются потоки - что-то еще происходит после завершения (типа пишет "Программа закончена"). Тогда уже я сам разберусь
Voody вне форума Ответить с цитированием
Старый 24.08.2009, 17:44   #10
Daramant
Форумчанин
 
Регистрация: 06.01.2009
Сообщений: 340
По умолчанию

Вот новая версия.

P.S. Если из потоков интенсивно изменять значения компонент на форме, то форма все равно подвисает.
Можно, конечно, поставить Application.ProcessMessages; после каждого Label.Caption := 'текст';, но тогда упадет скорость выполнения рассчетов в потоках.
Вложения
Тип файла: rar ThreadManager v2.0.rar (11.9 Кб, 244 просмотров)
Истинный успех – это то, что Вы сделали в сравнении с тем, что могли бы сделать.
Никогда не бойся делать то, что ты не умеешь. Помни, ковчег был построен любителем. Профессионалы построили "Титаник".

Последний раз редактировалось Daramant; 24.08.2009 в 20:27.
Daramant вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
ожидание внутри процедуры Juffin Общие вопросы Delphi 5 01.06.2009 13:52
Отображение текста до завершения скрипта Black_Parrot JavaScript, Ajax 5 05.12.2008 16:59
Ожидание окончания вызванного процесса Johnson Win Api 11 16.07.2008 23:11
Перехват завершения работы ОС vynt Win Api 7 19.05.2008 08:59
Ждать завершения чужого процесса ERASERROR Win Api 2 04.02.2008 08:23