Форум: "WinAPI";
Текущий архив: 2006.04.23;
Скачать: [xml.tar.bz2];
Внизwait functions Найти похожие ветки
← →
Набережных С. © (2006-02-01 17:39) [40]
> Лучше, ИМХО, периодически, ну скажем, раз в 30 секунд проверять
> три параметра
Тем более, что в большинстве случаев нет никакого смысла держать 100 активных потоков на одном процессоре.
← →
Игорь Шевченко © (2006-02-01 17:43) [41]Набережных С. © (01.02.06 17:39) [40]
А вот с числом потоков тут непросто, так как все зависит от задачи. Если обработка запроса ведет к монополизации процессора, то конечно, чем меньше потоков на один процессор, тем лучше, а если нет, то почему бы и (не сто, а, скажем, 10-20 потоков) не держать ?
← →
Набережных С. © (2006-02-01 18:03) [42]
> Игорь Шевченко © (01.02.06 17:43) [41]
> Если обработка запроса ведет к монополизации процессора,
> то конечно, чем меньше потоков на один процессор, тем лучше,
> а если нет, то почему бы и (не сто, а, скажем, 10-20 потоков)
> не держать ?
Да, конечно. Но я имел в виду именно активные потоки, монополизирующие процессор. И тут как раз порт завершения оказывается очень кстати, потому, что учитывает именно эти потоки, отбрасывая ожидающие чего либо, как известно. Без Completion Port такую функциональность получить непросто. Кстати, по приведенной мной ссылке есть и второй вариант пула, как раз для тех случаев, когда нужно активировать очередной поток независимо от загруженности.
← →
Игорь Шевченко © (2006-02-01 18:08) [43]Набережных С. © (01.02.06 18:03) [42]
<offtopic>
А вот в Vista, похоже, задача автора решается новыми API-функциями :)
</offtopic>
← →
Polevi © (2006-02-01 18:21) [44]>Набережных С. © (01.02.06 17:33) [39]
c загрузкой процессора и колво активных потоков врядли получится
дело в том что собствено задача - некий маршаллер, задача которго создать нужный COM объект и вызвать для него IDispatch.Invoke
что это за объект и что он делает маршаллер не знает
в основном объекты работат с БД
насчет порта завершения - откуда информация что он использует LIFO и есть ли уверенность что майкрософт не изменит алгоритм ?
← →
Polevi © (2006-02-01 18:33) [45]и наколько я понял NumberOfConcurrentThreads можно задать только один раз при создании порта
мне же это колво надо менять динамически
объекты работают с БД, поток может висеть из за блокировки ресурса к примеру
← →
Набережных С. © (2006-02-01 19:31) [46]
> Игорь Шевченко © (01.02.06 18:08) [43]
Замечательно, если так, задача-то не из простых. Особенно, если будет достаточно возможностей тонкой настройки.
> Polevi © (01.02.06 18:21) [44]
> c загрузкой процессора и колво активных потоков врядли получится
Почему? Загрузка легко измеряется счетчиком производительности. А с активными потоками - тебя должны будут интересовать только потоки твоего пула как индикатор активности пользователей, а их отследить не сложно. За активацию по мере освобождения процессора будет отвечать порт завершения, причем он будет учитывать именно реальное использование процессора. В том то и прелесть, что он позволяет максимально полно использовать минимизируя при этом непроизводительные потери на переключение потоков.
> насчет порта завершения - откуда информация что он использует
> LIFO
Ну как минимум от Рихтера. Где-то у него об этом есть довольно подробно. Далее собственные экспиременты. Ну и в MSDN вроде как тоже что-то видел по этому поводу.
> есть ли уверенность что майкрософт не изменит алгоритм ?
А нафига? Ты можешь предложить что-ни будь более эффективное?:)) Если запускать первым последний вошедший поток, то есть немалая вероятность, что этот поток еще не успел заснуть и, следовательно, получится экономия на работе с контекстом. Зачем же это менять? Да и не надо тебе заботиться, какой именно поток убивать. Какая разница? Главное, что их общее количество будет соответствовать ситуации, а об остальном позаботится порт.
> и наколько я понял NumberOfConcurrentThreads можно задать
> только один раз при создании порта
> мне же это колво надо менять динамически
> объекты работают с БД, поток может висеть из за блокировки
> ресурса к примеру
Да зачем же их менять?:) Это же количество одновременно активных потоков. Что, у тебя количество процессоров изменится во время работы?:))
> поток может висеть из за блокировки ресурса к примеру
Да пусть себе висит:) Как только какой-то поток перестанет использовать процессор, порт тут-же активирует новый поток, если в очереди есть запросы и есть ожидающий поток. А ожидающих ты можешь создать столько, сколько потребуется.
Пусть имеем 1 процессор. Создаем порт, задав ему 1 "конкурирующий" поток. Создаем 5 потоков и все их подключаем к порту. Постуил запрос, порт разбудил 1 поток, тот начал обработку. Допустим тут пришли еще несколько запросов - порт на них не реагирует. Тут активный поток обращается к девайсу и начинает ждать от него ответа, т.е. процессор ему не нужен. Порт тут же отреагирует на это и активирует следующий поток из подключенных к нему. Если и второй поток перейдет к ожиданию чего-либо, то порт тут же разбудит следующий поток. Т.е. порт не даст процессору простаивать, пока есть запросы в очереди и готовые их принять потоки. Разумеется, потом наступит момент когда требующих доступа к процессору потоков окажется больше, чем число процессоров и тут неизбежны переключения контекстов. Но, во-первых, такое положение продлится не долго, а во-вторых если проанализировать, то это все равно наилучший сценарий поведения из всех возможных - при других вариантах издержек оказывается больше.
← →
Набережных С. © (2006-02-01 19:38) [47]
>что он позволяет максимально полно использовать минимизируя
> при этом
"он позволяет максимально полно использовать процессоры, минимизируя при этом" и далее по тексту:)
← →
Polevi © (2006-02-02 08:19) [48]>Набережных С. © (01.02.06 19:31) [46]
дa, насчет NumberOfConcurrentThreads я запамятовал, туда 0 в моем случае надо передавать
написал тест все чудно работает, действительно LIFO, то что мне надо
вопрос с одновременным пробуждением нескольких потоков тоже элегантно решается передачей в PQCS счетчика
procedure TT.Execute;
var
bytes,key:Cardinal;
ov:POVERLAPPED;
begin
while not Terminated do
begin
if GetQueuedCompletionStatus(H, bytes, key, ov, 5000) then
begin
if bytes>1 then
PostQueuedCompletionStatus(H,bytes-1,0,nil);
...
...
...
end
else
if GetLastError()=WAIT_TIMEOUT then break;
end;
end;
спасибо за идею
← →
Набережных С. © (2006-02-02 17:07) [49]
> Polevi © (02.02.06 08:19) [48]
Извини за назойливость:), но я как-то не удовил, зачем рабочий поток вызывает PostQueuedCompletionStatus. Есть у транспорта 5 запросов - пусть он и вазывает эту функцию 5 раз подряд, а дело рабочих потоков - эти запросы обрабатывать. Или у тебя потоки занимаются и тем, и другим? Я так определял два ключа - CPKEY_RESTART и CPKEY_TERMINATE - и ими управлял. Если проснувшись поток получал CPKEY_TERMINATE, то он завершался, а если CPKEY_RESTART, то забирал очередную задачу из списка и обрабатывал ее. И насчет использование таймаутов тоже подумай еще раз. Потоки лучше удалять, когда больше делать нечего, а когда запросы более-менее регулярно приходят, лучше на это не отвлекаться. Ну висят без дела 5-10 лишних потоков - ну и пусть себе висят, кому они мешают? Наступит перерыв, тогда и удалить их можно. Да и желательно всегда иметь резерв на случай внезапного "взрыва" активности, а то навалятся запросы, а ты будешь тратить время на создание потоков, которые только что уничтожал.
IMHO, разумеется.
← →
Polevi © (2006-02-03 09:32) [50]>Набережных С. © (02.02.06 17:07) [49]
по поводу PQCS в рабочем потоке - так я избавился от цикла в транспортном потоке, т.е вызов ReleaseSemaphore(cnt) заменил на PostQueuedCompletionStatus(cnt), но можно было и цикл, конечно
ключи у меня определены аналогично твоим
я немного оттюнинговал проект, увеличил минимальное колво потоков в пуле до 5, время таймаута рабочего потока до 5 мин
процесс добавления , удаления потоков в пуле протоколируется вместе с информацией о минимуме-максимуме клиентов и потоков
запустил в работу один офис - это порядка 20 клиентов..
на основе логов возможно поменяю значения констант
Страницы: 1 2 вся ветка
Форум: "WinAPI";
Текущий архив: 2006.04.23;
Скачать: [xml.tar.bz2];
Память: 0.56 MB
Время: 0.015 c