Загрузка процессора не падает во время SleepEx ()

#winapi

#winapi

Вопрос:

Моя программа представляет собой слайд-шоу. Он выполняется на компьютере с другими процессами, поэтому, пока он ожидает отображения следующего слайда, я вызываю SleepEx (N, false), ожидая, что он уменьшит почти до нуля объем используемого процессора (N составляет от 100 мс до 5000 мс). На моей машине для разработки XP Pro именно это и происходит, но на домашней машине XP моего клиента во время SleepEx () регистрируется 30-80% процессора. Код представляет собой один поток, поэтому все, что использует весь этот процессор, находится в пределах вызова SleepEx (). Кто-нибудь видел это раньше?

Комментарии:

1. Вызываете ли вы что-нибудь высокоуровневое, которое запускает поток, например видеоплеер?

2. Не сознательно. Я использую библиотеку FreeImage для обработки преобразований изображений, но на данный момент для этого нет причин что-либо делать. И тот факт, что это нормально работает на моем компьютере, но не на компьютере клиента, вызывает недоумение.

3. Оффтопик: вызов Sleep — странный способ сделать это. Когда вы сделаете это, ваше приложение перестанет реагировать. Было бы лучше использовать таймер для запуска смены слайдов.

Ответ №1:

Какой процесс использует весь этот процессор? Если вы врываетесь в процесс с помощью отладчика — где в трассировке стека он тратит время?

Попробуйте использовать ProcDump для создания дампа процесса, когда он достигает этого скачка процессора. Затем проанализируйте трассировку стека, чтобы увидеть, где она застряла. Проделайте это несколько раз, и вы получите хорошую выборку того, на что он тратит время.

Комментарии:

1. Я предлагаю вам запустить удаленный дамп процесса в это загруженное время и проанализировать трассировку стека, чтобы увидеть, на что он тратит время

2. Извините — нажмите <Enter> преждевременно. У меня нет доступного отладчика.

3. Я выполнил ProcDump, и теперь у меня есть 1,5 Мб файла дампа, но я не знаю, что я должен использовать для его анализа. Загрузка процессора составляла 59%, а дамп был сделан примерно через 5 секунд после обновления экрана (за 35 секунд до следующего обновления)

4. Это то, о чем вам следует прочитать. Очень мощный инструмент отладки. В принципе, вы должны иметь возможность перенести этот файл дампа в Visual C или WinDbg, а затем увидеть трассировку стека (как если бы вы достигли точки останова).

5. Спасибо за попытку помочь, но я не уверен, что понимаю, к чему это приводит. Я знаю, что программа выполняет SleepEx (), и я знаю, что происходит перегрузка процессора, когда SleepEx () активен, потому что команда сразу после SleepEx () не выполнена. Похоже, вы просите меня отладить вызов API. Или я неправильно понял?

Ответ №2:

Я видел это раньше. Вы блокируете поток обработки сообщений главного окна.

Вам не следует размещать функцию Sleep() в однопоточном приложении, если оно имеет функцию обработки сообщений главного окна. Оконное приложение всегда должно обрабатывать оконные сообщения без заметной задержки, в другом случае это приведет к взаимоблокировке, по крайней мере, для приложения. Последствия зависят от платформы Windows, настроек компилятора и конфигурации процессора, обычно приложение в режиме отладки имеет временный обходной путь. Но если вы запустите такое приложение, скомпилированное с настройками выпуска, оно может использовать одно ядро процессора с функцией, которая заблокировала поток обработки сообщений в его главном окне.

Раздел Замечаний в описании функции MSDN Sleep() четко описывает эту ситуацию.

Вам просто нужно создать новый поток, чтобы использовать функцию Sleep () прямо там, чтобы разрешить свободный поток оконных сообщений в основном потоке.