Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > Большая задержка потока


Автор: borisbn 7.9.2011, 18:34
Добрый день !
Есть проблема:
Входные данные:
  Имеется устройство, генерящее прерывание ~1 раз в 7 мс.
  Есть драйвер, который передаёт управление из IRQ в DPC.
  В DPC дёргается семафор.
  В UserSpace этот семафор ждётся ф-цией WaitForSingleObject.
Проблема:
  Иногда (не часто) получается так, что ф-ция WaitForSingleObject зависает на 40...50 мс, а затем "выстреливает" 6-7 раз.  Такой ситуации легче добиться, если таскать, сворачивать/разворачивать окошки (видеокарта на компе встроенная, т.е. ооооч. хилая и вся прорисовка делается ЦП).
  Если поставить потоку TIME_CRITICAL, то такая ситуация проявляется гораздо реже.

Пробовал
Код
SetProcessPriorityBoost( GetCurrentProcess(), TRUE /* FALSE тоже пробовал */ )

для процесса и
Код
SetThreadPriorityBoost( m_hThreadHandle, TRUE /* FALSE тоже пробовал */ )

для потока. Ничего не изменилось.

Вопрос:
Нормально ли это ?
Если нет, то как этого можно избежать ?

P.S. Пробовал на WinXP и на семёрке - одинакого.
P.P.S. Сложно поверить, что у какого-то потока в венде приоритет равен (или выше) TIME_CRITICAL и ему выделяется слайс до 50 (!!!) мс. 500...1000 мкс - ещё поверю, но 50 мс ???

Автор: Alca 7.9.2011, 19:38
Что значит выстреливает?

Автор: borisbn 7.9.2011, 22:13
Цитата(Alca @  7.9.2011,  19:38 Найти цитируемый пост)
Что значит выстреливает?

Нормальная ситуация, когда WaitForSingleObject отдаёт мне управление каждые 7 мс.
Ненормальная - это когда вызов Wait'а стопорится на 50 мс, а затем (т.к. он вызывается в цикле) я получаю управление 7 раз подряд без задержки.
код потока в UserSpace
Код

while ( true ) {
    if ( WaitForSingleObject( m_semaphore, ... ) {
        doSomething();
    }
}

так вот иногда doSomething вызывается каждые 7 мс, а иногда с задержкой 50 мс, а затем 7 раз без задержки

Автор: feodorv 7.9.2011, 22:34
На мой взгляд, 7 миллисекунд для UserSpace - это слишком часто. В системе, в которой запущен только Ваш процесс, присутствуют ещё 30-50 потоков, которые могут простаивать, а могут и нет. Ещё возможны задержки, возникающие при работе с файловой системой: запись логов, своппинг и т.д. Как там работает механизм выделения квантов времени - известно Богу и Майкрософт.

Автор: Alexeis 7.9.2011, 22:59
  Винда не гарантирует, что после переключения семафора процессорное время будет передано потоку, который был заблокирован на этом семафоре. Однако, если есть 2+ ядра и высокий приоритет у юзер потока, то такая ситуация очень вероятна. На самом деле, даже в юзер моде за одну миллисекунду активировать и усыплять 2 потока попеременно раз 50 наверное. Так что на винде легко можно переключать потоки с частотой 7мс. 15мс это квант времени который может израсходовать поток, но если он досрочно засыпает, то оставшееся время передается другому потоку, если и тот уснет, а у первого будет работа, то первый продолжит работать, хотя 15мс тика таймера еще не прошли. Фактически быстродействие переключения будет зависеть от частоты процессора.

Автор: borisbn 8.9.2011, 00:23
Alexeis, не совсем понял - так 50 мс, которые мой поток не получае управление, это нормально или нет ?
Мне кажется, что нет...

Автор: volatile 8.9.2011, 01:40
Цитата(borisbn @  7.9.2011,  18:34 Найти цитируемый пост)
Сложно поверить, что у какого-то потока в венде приоритет равен (или выше) TIME_CRITICAL 

borisbn, в венде на самом деле их куча.
здесь просто есть некоторая путаница в названиях.
Проще приоритет выражать в цифрах. так вот, TIME_CRITICAL для обычного процесса это приоритет 15.
А максимальный приоритет это 31. То есть у системы может быть куча процессов с более высоким приоритетом.

Кроме самого приоритета, нужно выставить еще класс приоритета для процесса.
Посмотрите функцию: SetPriorityClass ()
При классе REALTIME, приоритет TIME_CRITICAL будет равен = 31.

Добавлено через 6 минут и 26 секунд
Но вообще поостороже с такими приоритетами, если зависнет, то только кнопка ресет выручит  smile 

Автор: GremlinProg 8.9.2011, 06:15
Цитата(borisbn @  8.9.2011,  00:13 Найти цитируемый пост)
так вот иногда doSomething вызывается каждые 7 мс, а иногда с задержкой 50 мс, а затем 7 раз без задержки

Цитата(Alexeis @  8.9.2011,  00:59 Найти цитируемый пост)
Винда не гарантирует, что после переключения семафора процессорное время будет передано потоку, который был заблокирован на этом семафоре.

тут стоит учесть 2 вещи:
1. doSomething тоже кушает какое-то время
2. реализация драйвера: повышение приоритета может влиять косъвенно ( через другие у-ва: мышь, видеокарта и т.п. ), а вот реализация сигнальной модели - напрямую (там может кОпится очередь событий?) и тут уже не так важно будет, как часто ось способна переключать контекст

Добавлено через 5 минут и 48 секунд
хотя, вот только обратил внимание:
Цитата(borisbn @  7.9.2011,  20:34 Найти цитируемый пост)
В DPC дёргается семафор.

семафор на то и нужен, чтобы его можно было разом разрядить несколькими разрядами, например: в несколько потоков, на нескольких ядрах,
и раз он был выбран, значит на то была причина, которая скорее всего оглашена в документации

Добавлено через 8 минут и 34 секунды
возможно, это и есть реализация той самой очереди: зачем активировать несколько раз подряд одно и то же событие, если знаешь точно, что они уже произошли, проще и быстрее разрядить один семафор, по-моему, все логично

Автор: Alexeis 8.9.2011, 08:31
borisbn, нормально или нет зависит от других задач, которые ждут своей очереди, а также от их приоритета. Если таковые имеются и их приоритет выше, тогда и задержки в несколько секунд могут будут нормальными

Автор: borisbn 8.9.2011, 13:54
Цитата(Alexeis @  8.9.2011,  08:31 Найти цитируемый пост)
нормально или нет зависит от других задач, которые ждут своей очереди, а также от их приоритета

Все задачи, кроме моей - стандартные потоки/программы венды. Особенно сильно начинает тормозить мой поток когда я загружаю ГУИ (двигаю или разворачиваю/сворачиваю) окошки (не своей программы, а любой другой). Получается, что у ГУИ приоритет выше, чем у моей программы ?

Добавлено через 12 минут и 11 секунд
Цитата(GremlinProg @  8.9.2011,  06:15 Найти цитируемый пост)
1. doSomething тоже кушает какое-то время

от 200 до 300 мкс. Т.е. с головой. Даже когда я получаю 7 прерываний подряд.

Цитата(GremlinProg @  8.9.2011,  06:15 Найти цитируемый пост)
и раз он был выбран, значит на то была причина, которая скорее всего оглашена в документации

Плата, драйвер и программа - наши, т.е. документацию я и буду писать smile
Семафор выбрал потому, что рассчитывал на возможную задержку, но на одну. Ну, максимум две (14 мс). Но не на 6-7...

Автор: volatile 9.9.2011, 00:05
Цитата(borisbn @  8.9.2011,  13:54 Найти цитируемый пост)
что у ГУИ приоритет выше, чем у моей программы ?

У курсора мыши например, один из самых высоких приоритетов в системе.

Автор: borisbn 9.9.2011, 09:23
Цитата(volatile @  9.9.2011,  00:05 Найти цитируемый пост)
У курсора мыши например, один из самых высоких приоритетов в системе.

Вот же ж чйорт, знал же о курсоре  smile  volatile, спасибо!
Скорее всего в этом и дело, потому, что когда запускаю параллельно архивирование какого-нибудь фильма, таких выбросов не наблюдается.
Что ж, оооооч. не хотелось, но придётся, наверное, переходить на какой-нить QNX.
Помечаю как решённый, но если у кого-нибудь ещё будут мысли - велкам smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)