![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
узнать о завершении потока
sunnmas © (2009-08-03 20:08:00)Есть поток 1, который запускает множество потоков 2 и только и делает, что следит за состоянием этих, запущенных им потоков 2. Эти потоки 2 завершают свою работу и разлагаются)). Таких потоков 2 может быть ограниченное число (определяется пользователем).
Вопрос: как узнать что потоки 2 уже заканчивают свою работу, чтобы запускать новые?
Поток 1:
цикл
Если потоков мало то
создать нужн. кол-во потоков
запоминаем на них ссылки в списке
фриОнТерминатед = тру
запустить потоки
конецесли
Здесь нужно вычислить сколько потоков из списка завершились,
т.е. узнать на сколько потоков стало меньше. Как?
конеццикла
Rouse_ (2009-08-04 13:44:00) [1]Можно сделать простым, но несколько ресурсоемким способом:
Пусть поток 1 создаст столько потоков, сколько нужно для решения задачи, а потоки 2 синхронизируй между собой через семафор, в котором и выставляй лимит на количество работающих потоков.
Например:
ThreadPool := CreateSemaphore(nil, ServerSettings.ThreadsCount,
ServerSettings.ThreadsCount, nil);
Соответственно метод Execute потока у тебя должен выглядеть примерно так:
procedure TTestThread.Execute;
begin
case WaitForSingleObject(ThreadPool, INFINITE) of
WAIT_FAILED:
begin
Synhronize(RequestFailed);
Exit;
end;
WAIT_OBJECT_0:
try
// код потока
finally
ReleaseSemaphore(ThreadPool, 1, nil);
end;
end;
end;
Leonid Troyanovsky (2009-08-04 07:46:00) [2]
> sunnmas © (03.08.09 20:43) [3]
> Юрий Зотов, я бы не хотел затрагивать поток vcl.
Почему, собс-но? Вполне достойный поток.
> Pirog, сейчас попробую)
Можно и не пробовать.
> sunnmas © (03.08.09 20:08)
> Вопрос: как узнать что потоки 2 уже заканчивают свою работу,
WaitForMultipleObjects(Ex), RTFM: msdn. До 64 потоков.
> чтобы запускать новые?
А вот это - не дело. Читать:
http://rsdn.ru/?article/baseserv/threadpool.xml
--
Regards, LVT.
тимохов (2009-08-03 23:44:00) [3]Если нужно только количество потоков, а не сами потоки, то можно в начале Execute потока 2 делать inc некой глобальной переменной, а в конце Execute делать dec. При этом естественно использовать средства синхронизации - либо критические секции, либо interlockedincrement/interloceddecrement.
sunnmas (2009-08-03 20:43:00) [4]Юрий Зотов, я бы не хотел затрагивать поток vcl. Но OnTerminate выполняется в контексте этого потока (vcl). Менеджер (поток 1) же выполняется параллельно ему вместе с потоками 2.
Pirog, сейчас попробую)
Юрий Зотов (2009-08-03 20:35:00) [5]Поток 1 (менеджер) хранит список потоков 2 (TObjectList). При создании каждого потока 2 менеджер заносит его в этот список и назначает ему обработчик события OnTerminate (FreeOnTerminate - не нужно, это будет лишним). Когда каждый поток 2 завершается, срабатывает это событие и в его обработчике только что завершившийся поток (Sender) удаляется из списка (а список при этом автоматически уничтожит сам объект "поток").
Все очень просто и не нужно никаких циклов. А счетчик уже есть у списка TObjectList.
Pirog (2009-08-03 20:22:00) [6]ха....проще простого
цикл
Если потоков мало то
создать нужн. кол-во потоков
запоминаем на них ссылки в списке
фриОнТерминатед = тру
запустить потоки
конецесли
лист.потоков.коунт
конеццикла