Суть проблемы.

Ваше запущенное приложение в какой то момент начинает активно грузить CPU, вас зовёт тестер и просит починить это!

Какие обычные действия программистов в таком случае?

  • Просят локализовать, если получается, то решить проблему вопрос времени.
  • Начинается добавление логов, счетчиков проходов и тому подобного. Все отдается тестеру или заказчику с требованием воспроизвести и вернуть лог на анализ. Хорошо если воспроизвести удастся и все станет ясно.
  • Предположить время, когда "все работало" и по изменениями в системе контроля версий искать возможные причины.


Как проще поступить вэтом случае?

означает, что какой то поток(и) обработки данных проснулся\запустился, и стал активно выполнять свою работу или иногда просто зациклился. Узнав стек выполнения в момент нагрузки, можно с высокой долей вероятности понять причину такого поведения.

Как же его можно узнать, ведь мы не находимся под отладчиком ?Лично я пользуюсь утилитой Process Explorer дающая возможность увидеть список потоков и их стек . Программа установки не требует.

Для демонстрации я запустил свое приложение с именем процесса "Qocr.Application.Wpf.exe ", в которое добавил фейковый код бесконечного цикла . Теперь давайте найдём причину загрузки ядра без отладчика . Для этого я иду в ствойства процесса, далее:

  1. Переходим на вкладку Threads и видим, что имеется 1 поток, который грузит на 16% CPU .
  2. Выделяем этот поток и жмем Stack, открылось окно "Stack for thread ID ".
  3. В окне видим, что наш поток был создан тут Qocr.Application.Wpf.exe!<>c. b__36_1+0x3a и в данный момент вызывает GetDirectories из метода InitLanguages().

Продемонстрирую действия выше на изображении со стрелками:

Открыв исходный код программы и перейдя к методу InitLanguages можно увидеть мой фейковый код. Зная эту информацию, а именно место отстановки, можно уже принимать меры.

Код стека (из примера выше) вызывающий бесконечный цикл (Можно проверить):

Private void InitLanguages() { new Thread (() => { while (true ) { var dir = Directory .GetDirectories(@"C:\" ); } ; }).Start(); }

Ложка дегтя в бочке с медом.

Два момента, которые стоит знать, если решите воспользоваться способом выше:
  1. Потоки созданные CLR (созданные в коде .NET приложения) после останова не продолжают выполнение. В результате чего поток останавливается и остается висеть до перезапуска программы.
  2. Если стек исполнения не содержит полезной информации, то стоит проделать остановку и просмотр стека несколько раз. Вероятность наткнуться на место зацикливания очень велика.
  • Перевод
  • Tutorial

От переводчика: данная статья является седьмой в цикле переводов официального руководства по библиотеке SFML. Прошлую статью можно найти Данный цикл статей ставит своей целью предоставить людям, не знающим язык оригинала, возможность ознакомится с этой библиотекой. SFML - это простая и кроссплатформенная мультимедиа библиотека. SFML обеспечивает простой интерфейс для разработки игр и прочих мультимедийных приложений. Оригинальную статью можно найти . Начнем.

Что такое поток?

Большая часть из вас уже знает, что такое поток, однако объясним, что это такое, для новичков в данной теме.

Поток - это по сути последовательность инструкций, которые выполняются параллельно с другими потоками. Каждая программа создает по меньшей мере один поток: основной, который запускает функцию main(). Программа, использующая только главный поток, является однопоточной; если добавить один или более потоков, она станет многопоточной.

Так, короче, потоки - это способ сделать несколько вещей одновременно. Это может быть полезно, например, для отображения анимации и обработки пользовательского ввода данных во время загрузки изображений или звуков. Потоки также широко используется в сетевом программировании, во время ожидания получения данные будет продолжаться обновление и рисование приложения.

Потоки SFML или std::thread?

В своей последней версии (2011), стандартная библиотека C++ предоставляет набор классов для работы с потоками . Во время написания SFML, стандарт C++11 еще не был написан и не было никакого стандартного способа создания потоков. Когда SFML 2.0 был выпущен, было много компиляторов, которые не поддерживали этот новый стандарт.

Если вы работаете с компилятором, который поддерживает новый стандарт и содержит заголовочный файл, забудьте о классах потоков SFML и используйте стандартные классы C++ вместо них. Но, если вы работаете с компилятором, не поддерживающим данный стандарт, или планируете распространять ваш код и хотите добиться полной портируемости, потоковые классы SFML являются хорошим выбором

Создание потоков с помощью SFML

Хватит разглагольствований, давайте посмотрим на код. Класс, дающий возможность создавать потоки с помощью SFML, называется sf::Thread , и вот как это (создание потока) выглядит в действии:

#include #include void func() { // эта функция запускается когда вызывается thread.launch() for (int i = 0; i < 10; ++i) std::cout << "I"m thread number one" << std::endl; } int main() { // создание потока с функцией func в качестве точки входа sf::Thread thread(&func); // запуск потока thread.launch(); // главные поток продолжает быть запущенным... for (int i = 0; i < 10; ++i) std::cout << "I"m the main thread" << std::endl; return 0; }
В этом коде функции main и func выполняются параллельно после вызова thread.launch(). Результатом этого является то, что текст, выводимый обеими функциями, смешивается в консоли.

Точка входа в поток, т.е. функция, которая будет выполняться, когда поток запускается, должна быть передана конструктору sf::Thread . sf::Thread пытается быть гибким и принимать различные точки входа: non-member функции или методы классов, функции с аргументами или без них, функторы и так далее. Приведенный выше пример показывает, как использовать функцию-член, вот несколько других примеров.

  • non-member функция с одним аргументом:

    Void func(int x) { } sf::Thread thread(&func, 5);

  • метод класса:

    Class MyClass { public: void func() { } }; MyClass object; sf::Thread thread(&MyClass::func, &object);

  • функтор (функциональный объект):

    Struct MyFunctor { void operator()() { } }; sf::Thread thread(MyFunctor());

Последний пример, который использует функтор, является наиболее мощным, поскольку он может принимать любые типы функторов и поэтому делает класс sf::Thread совместимым со многими типами функций, которые напрямую не поддерживаются. Эта функция особенно интересна с лямбда-выражениями C++11 или std::bind.

// с лямбда-функцией sf::Thread thread((){ std::cout << "I am in thread!" << std::endl; });
// с std::bind void func(std::string, int, double) { } sf::Thread thread(std::bind(&func, "hello", 24, 0.5));
Если вы хотите использовать sf::Thread внутри класса, не забудьте, что он не имеет стандартного конструктора. Поэтому, вы должны инициализировать его в конструкторе вашего класса в списке инициализации:

Class ClassWithThread { public: ClassWithThread() : m_thread(&ClassWithThread::f, this) { } private: void f() { ... } sf::Thread m_thread; };
Если вам действительно нужно создать экземпляр sf::Thread после инициализации объекта, вы можете создать его в куче.

Запуск потока

После того, как вы создали экземпляр sf::Thread , вы должны запустить его с помощью запуска функции.

Sf::Thread thread(&func); thread.launch();
launch вызывает функцию, которую вы передали в конструктор нового потока, и сразу же завершает свою работу, так что вызывающий поток может сразу же продолжить выполнение.

Остановка потоков

Поток автоматически завершает свою работу, когда функция, служащая точкой входа для данного потока, возвращает свое значение. Если вы хотите ждать завершения потока из другого потока, вы можете вызвать его функцию wait.

Sf::Thread thread(&func); // запуск потока thread.launch(); ... // выполнение блокируется до тех пор, пока поток не завершится thread.wait();
Функция ожидания также неявно вызывается деструктором sf::Thread , так что поток не может оставаться запущенным (и бесконтрольным) после того, как его экземпляр sf::Thread уничтожается. Помните это, когда вы управляете вашими потоками (смотрите прошлую секцию статьи).

Приостановка потока

В SFML нет функции, которая бы предоставляла способ приостановки потока; единственный способ приостановки потока - сделать это из кода самого потока. Другими словами, вы можете только приостановить текущий поток. Что бы это сделать, вы можете вызвать функцию sf::sleep:

Void func() { ... sf::sleep(sf::milliseconds(10)); ... }
sf::sleep имеет один аргумент - время приостановки. Это время может быть выражено в любой единице, как было показано в статье про .

Обратите внимание, что вы можете приостановить любой поток с помощью данной функции, даже главный поток.

Sf::sleep является наиболее эффективным способом приостановить поток: на протяжении приостановки потока, он (поток) практически не потребляет ресурсы процессора. Приостановка, основанная на активном ожидании, вроде пустого цикла while, потребляет 100% ресурсов центрального процессора и делает… ничего. Однако имейте в виду, что продолжительность приостановки является просто подсказкой; реальная продолжительность приостановки (больше или меньше указанного вами времени) зависит от ОС. Так что не полагайтесь на эту функцию при очень точном отсчете времени.

Защита разделяемых данных

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

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

Наиболее распространенным (и используемым) примитивом является мьютекс. Мьютекс расшифровывается как «Взаимное исключение». Это гарантия, что только один поток может выполнять код. Посмотрим, как мьютексы работают, на примере ниже:

#include #include sf::Mutex mutex; void func() { mutex.lock(); for (int i = 0; i < 10; ++i) std::cout << "I"m thread number one" << std::endl; mutex.unlock(); } int main() { sf::Thread thread(&func); thread.launch(); mutex.lock(); for (int i = 0; i < 10; ++i) std::cout << "I"m the main thread" << std::endl; mutex.unlock(); return 0; }
Этот код использует общий ресурс (std::cout), и, как мы видим, это приводит к нежелательным результатам. Вывод потоков смешался в консоли. Чтобы убедиться в том, что вывод правильно напечатается, вместо того, чтобы быть беспорядочно смешанным, мы защищаем соответствующие области кода мьютексом.

Первый поток, который достигает вызова mutex.lock(), блокирует мьютекс и получает доступ к коду, который печатает текст. Когда другие потоки достигают вызова mutex.lock(), мьютекс уже заблокирован, и другие потоки приостанавливают свое выполнение (это похоже на вызов sf::sleep, спящий поток не потребляет время центрального процессора). Когда первый поток разблокирует мьютекс, второй поток продолжает свое выполнение, блокирует мьютекс и печатает текст. Это приводит к тому, что текст в консоли печатается последовательно и не смешивается.

Мьютекс - это не только примитив, который вы можете использовать для защиты разделяемых данных, вы можете использовать его во многих других случаях. Однако, если ваше приложение делает сложные вещи при работе с потоками, и вы чувствуете, что возможностей мьютексов недостаточно - не стесняйтесь искать другую библиотеку, обладающую большим функционалом.

Защита мьютексов

Не волнуйтесь: мьютексы уже потокобезопасны, нет необходимости их защищать. Но они не безопасны в плане исключений. Что происходит, если исключение выбрасывается, когда мьютекс заблокирован? Он никогда не может быть разблокирован и будет оставаться заблокированным вечно. Все потоки, пытающиеся разблокировать заблокированный мьютекс, будут заблокированы навсегда. В некоторых случаях, ваше приложение будет «заморожено».

Чтобы быть уверенным, что мьютекс всегда разблокирован в среде, в которой он (мьютекс) может выбросить исключение, SFML предоставляет RAII класс, позволяющий обернуть мьютекс в класс sf::Lock. Блокировка происходит в конструкторе, разблокировка происходит в деструкторе. Просто и эффективно.

Sf::Mutex mutex; void func() { sf::Lock lock(mutex); // mutex.lock() functionThatMightThrowAnException(); // mutex.unlock(), если функция выбросит исключение } // mutex.unlock()
Помните, что sf::Lock может также быть использован в функциях, которые имеют множество возвращаемых значений.

Sf::Mutex mutex; bool func() { sf::Lock lock(mutex); // mutex.lock() if (!image1.loadFromFile("...")) return false; // mutex.unlock() if (!image2.loadFromFile("...")) return false; // mutex.unlock() if (!image3.loadFromFile("...")) return false; // mutex.unlock() return true; } // mutex.unlock()

Распространенные заблуждения

Вещь, часто упускаемая из виду: поток не может существовать без соответствующего экземпляра

5.6. Уплотняем поток загрузки

Рассмотрев методы сжатия, объединения, кэширования и создания параллельных соединений, разумно было бы озадачиться следующим вопросом: какая часть страницы должна загружаться вместе с основным HTML-файлом, а какая - только с внешними файлами?

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

Кроме того, были проведены теоретические выкладки для определения оптимального распределения загрузки по стадиям с учетом всех аспектов.

Из книги Разгони свой сайт автора Мациевский Николай

Итоговая таблица Ниже приведены все результаты оптимизации для отдельной взятой страницы. Загрузка тестировалась на соединении 100 Кб/с, общее число первоначальных объектов: 23. Номер шага Описание Общий размер (кб) Время загрузки (мс) 1Обычная страница. Ничего не сжато

Из книги Iptables Tutorial 1.1.19 автора Andreasson Oskar

Из книги ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ВСТРОЕННЫХ СИСТЕМ. Общие требования к разработке и документированию автора Госстандарт России

Из книги Linux для пользователя автора Костромин Виктор Алексеевич

2.4.3. Варианты загрузки Итак, на мой взгляд, выбор варианта загрузки производится следующим образом: Если у вас установлена Windows NT или Windows 2000, то используйте NT Loader. Если у вас стоит Windows 95 или Windows 98 на FAT16, и вы не хотите ставить программу-загрузчик из другой ОС или от

Из книги 200 лучших программ для Интернета. Популярный самоучитель автора Краинский И

8.2. Процедура загрузки ОС Linux Для начала надо отметить, что все, о чем будет рассказано в этом разделе, относится к дистрибутиву Red Hat и его аналогам. В других дистрибутивах (например, Debian) процедуры загрузки могут быть организованы иначе.

Из книги Asterisk™: будущее телефонии Второе издание автора Меггелен Джим Ван

Менеджеры загрузки Ничто так не раздражает пользователя Интернета, как медленная скорость загрузки. Решать эту проблему можно по-разному. Можно использовать различные браузеры и выбрать самый быстрый или накопить денег и купить дорогой модем, который будет уверенно

Из книги TCP/IP Архитектура, протоколы, реализация (включая IP версии 6 и IP Security) автора Фейт Сидни М

Протокол, используемый для загрузки Телефоны Polycom могут загружать свою конфигурацию по одному из трех протоколов: TFTP, HTTP и FTP.Сразу же хотим попросить избегать TFTP. Он не обеспечивает необходимой безопасности, и телефон не может использовать информацию о дате для

Из книги Самоучитель работы на Macintosh автора Скрылина Софья

11.11 Параметры загрузки Параметры таблицы 11.1 могут содержаться в ответах протоколов BOOTP или DHCP, а параметры таблицы 11.2 могут использоваться только в DHCP.Таблица 11.2 Параметры DHCP Дополнительные параметры только для DHCP Requested IP Address (запрошенный IP-адрес) Клиент запросил

Из книги Первые шаги с Windows 7. Руководство для начинающих автора Колисниченко Денис Н.

4.1.6. Папка Загрузки Нажатие на кнопку Сохранить (Save), расположенную в заголовке письма, приводит к автоматическому сохранению прикрепленных файлов в папке Загрузки (Downloads), которая находится в домашней папке пользователя (рис. 4.21). Ее можно открыть, как любую папку, в окне

Из книги Linux: Полное руководство автора Колисниченко Денис Николаевич

2.4.4. Включение загрузки с DVD Чтобы загрузиться с установочного диска Windows, нужно изменить порядок загрузки в BIOS Setup (чтобы система загружалась с DVD, а не с жесткого диска). В случае со стационарным компьютером для входа в BIOS Setup обычно достаточно нажать клавишу сразу,

Из книги Adobe Flash. Создание аркад, головоломок и других игр с помощью ActionScript автора Розенцвейг Гэри

9.1.2. Продолжение загрузки. Демон initС момента загрузки ядра процесс начальной загрузки системы идет под управлением самой системы. Первой получает управление процедура автозапуска ядра. Она определяет объем доступной оперативной памяти, тип и быстродействие процессора,

Из книги Как раскрутить и разрекламировать Web-сайт в сети Интернет автора Загуменов Александр Петрович

Экран загрузки Хотя вы всегда должны стремиться, чтобы размер готового файла был минимальным, у вас наверняка будут ролики, загрузка которых займет больше, чем несколько секунд при работе через модем. Если игра имеет размер в сотни килобайт, у некоторых пользователей ее

Из книги Linux глазами хакера автора Флёнов Михаил Евгеньевич

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

Из книги Windows 10. Секреты и устройство автора Алмаметов Владимир

3.2.4. Интересные настройки загрузки Рассмотрим парочку файлов, которые хоть и незначительно, но влияют на загрузку.Прежде чем появится приглашение ввести пароль, на экране отображается текстовая информация, пояснение. Чаще всего, здесь разработчик пишет имя дистрибутива

Из книги автора

10.3.2. Контроль загрузки файлов Загрузка файлов - самая опасная возможность для сервера. Каждый пользователь должен иметь право обращаться только к своей директории. А что делать, чтобы анонимные пользователи тоже могли работать с файлами? В этом случае нужно по

Состояния потоков и планирование их выполнения


Для каждого созданного потока в системе предусматриваются три возможных его состояния:

  • состояние выполнения, когда код потока выполняется процессором; на однопроцессорных платформах в этом состоянии в каждый момент времени может находиться только один поток;
  • состояние готовности к выполнению, когда поток готов продолжать свою работу и ждет освобождения ЦП;
  • состояние ожидания наступления некоторого события; в этом случае поток не претендует на время ЦП, пока не наступит определенное событие (завершение операции ввода/вывода, освобождение необходимого потоку занятого ресурса, сигнала от другого потока); часто такие потоки называют блокированными.
Изменение состояния потока происходит в результате соответствующих действий. Удобно для этих целей использовать следующую диаграмму состояний и переходов.

Переходы между состояниями можно описать следующим образом:

  • «готовность» → «выполнение»: система в соответствии с алгоритмом планирования выбирает для выполнения текущий поток, предоставляя ему ЦП
  • «выполнение» → «готовность»: поток готов продолжать свою работу, но система принимает решение прервать его выполнение; чаще всего это происходит по следующим двум причинам:
    • завершается выделенное потоку время владения процессором;
    • в числе готовых к выполнению появляется более приоритетный поток по сравнению с текущим;
  • «выполнение» → «ожидание»: дальнейшее исполнение кода текущего активного потока невозможно без наступления некоторого события, и поэтому активный поток прерывает свое выполнение и переводится системой в состояние ожидания (блокируется);
  • «ожиданием» → «готовность»: в системе происходит некоторое событие, наступление которого ожидает один из блокированных потоков, и поэтому система переводит этот поток в состояние готовности (разблокирует), после чего он будет учитываться системой при планировании порядка предоставления ЦП;
  • наконец, поток может нормально или аварийно завершить свое выполнение, после чего система удаляет его дескриптор из своей внутренней структуры, и тем самым поток перестает существовать.
В состояниях готовности и ожидания может находиться несколько потоков, поэтому система создает для хранения их дескрипторов отдельные списковые структуры. Организация этих списков зависит от тех принципов, которые положены в основу планирования потоков для данной ОС.

Цель планирования потоков вполне очевидна - определение порядка выполнения потоков в условиях внешней или внутренней многозадачности. Однако способы достижения этой цели существенно зависят от типа ОС. Рассмотрим сначала принципы планирования для универсальных ОС. Для таких ОС нельзя заранее предсказать, сколько и какие потоки будут запущены в каждый момент времени и в каких состояниях они будут находиться. Поэтому планирование должно выполняться динамически на основе сбора и анализа информации о текущем состоянии вычислительной системы.

Для этого в состав ОС включается модуль-планировщик, реализующий выбранные алгоритмы планирования. Поскольку этот модуль представляет собой программный код, то для решения своих задач планировщик должен на некоторое время забирать ЦП. Отсюда следует, что алгоритмы планирования должны быть максимально простыми, иначе возникает опасность, что система будет тратить недопустимо большое время на решение своих внутренних задач, а на выполнение прикладных программ времени не останется.

Кроме вычислительной простоты, алгоритмы планирования должны обладать следующими общими свойствами:

  • обеспечение максимально возможной загрузки ЦП;
  • обеспечение равномерной загрузки ресурсов вычислительной системы;
  • обеспечение справедливого обслуживания всех процессов и потоков;
  • минимизация времени отклика для интерактивных процессов.
За время существования ОС было предложено и реализовано несколько принципов управления потоками. В настоящее время большинство универсальных ОС используют метод вытесняющей многозадачности (preemptive multitasking), который тоже имеет несколько разновидностей. В основе метода лежат два важнейших и достаточно понятных принципа: квантование времени ЦП и приоритеты потоков.

Квантование означает, что каждому потоку система выделяет определенный интервал времени (квант), в течение которого процессор потенциально может выполнять код этого потока. По завершении выделенного кванта планировщик принудительно переключает процессор на выполнение другого готового потока (если, конечно, такой есть), переводя старый активный поток в состояние готовности. Это гарантирует, что ни один поток не захватит ЦП на непозволительно большое время (как было в более ранних системах с так называемой невытесняющей или кооперативной многозадачностью). Конечно, выделенный квант поток может и не использовать до конца, если в процессе своего выполнения он нормально или аварийно завершится, или потребует наступления некоторого события, или будет прерван системой.

Для эффективной работы ОС большое значение имеет выбор величины кванта. Очень маленькие значения кванта приводят к частым переключениям ЦП, что повышает непроизводительные расходы из-за необходимости постоянного сохранения контекста прерываемого потока и загрузки контекста активизируемого потока. Наоборот, большие значения кванта уменьшают иллюзию одновременного выполнения нескольких приложений. Некоторые планировщики умеют изменять кванты в определенных пределах, увеличивая их для тех потоков, которые не используют до конца выделенное время, например, из-за частых обращений к операциям ввода/вывода. Типичный диапазон изменения кванта – от 10 до 50 миллисекунд. При этом необходимо учитывать все возрастающие скорости работы современных процессоров: за 10 миллисекунд (т.е. за 1/100 секунды) процессор успеет выполнить около 10 млн. элементарных команд.

Можно связать величину кванта с приоритетом потока. Приоритет определяет важность потока и влияет на частоту запуска потока и, возможно, на величину выделяемого кванта. Интуитивно понятно, что потоки могут иметь разную степень важности: системные – более высокую (иначе ОС не сможет решать свои задачи), прикладные – менее высокую. Многие ОС позволяют группировать потоки по их важности, выделяя три группы, или класса:

  • потоки реального времени с максимально высоким уровнем приоритета;
  • системные потоки с меньшим уровнем приоритета;
  • прикладные потоки с самым низким приоритетом.
Внутри каждой группы выделяется свой диапазон возможных значений приоритетов, причем эти диапазоны между собой не пересекаются, т.е. максимально возможный приоритет прикладного потока всегда будет строго меньше минимально возможного приоритета для системных потоков. Внутри каждой группы могут использоваться разные алгоритмы управления приоритетами.

Если приоритет потока может меняться системой, то такие приоритеты называют динамическими, иначе – фиксированными. Конечно, реализация фиксированных приоритетов гораздо проще, тогда как динамические приоритеты позволяют реализовать более справедливое распределение процессорного времени. Например, потоки, интенсивно использующие внешние устройства, очень часто блокируются до завершения выделенного кванта времени, т.е. не используют эти кванты полностью. Справедливо при разблокировании таких потоков дать им более высокий приоритет для быстрой активации, что обеспечивает большую загрузку относительно медленных внешних устройств. С другой стороны, если поток полностью расходует выделенный квант, система может после его приостановки уменьшить приоритет. Тем самым, более высокие приоритеты получают более короткие потоки, быстро освобождающие процессор, и следовательно, достигается более равномерная загрузка вычислительной системы в целом.

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

Для реализации приоритетного обслуживания ОС должна создавать и поддерживать набор приоритетных очередей. Для каждого возможного значения приоритета создается своя очередь, в которую потоки (в виде своих дескрипторов) помещаются строго в соответствии с очередностью. Планировщик просматривает эти очереди по порядку следования приоритетов и выбирает для выполнения первый поток в самой приоритетной непустой очереди. Отсюда следует, что потоки с меньшими приоритетами будут выполняться, только если пусты все более приоритетные очереди. Если допускается изменение приоритета, то планировщик должен уметь перемещать поток в другую очередь в соответствии с новым значением приоритета.

Схематично массив приоритетных очередей представлен на следующем рисунке, где для удобства более приоритетные потоки собраны в левой части массива, менее приоритетные – в правой, а сами приоритеты изменяются от 1 (максимум) до n (минимум). Условное обозначение «поток i.2» показывает, что данный поток имеет приоритет i и стоит вторым по порядку в своей очереди.

Для изменения приоритета и, возможно, кванта времени планировщику необходима следующая информация: базовая величина приоритета и кванта, время ожидания в очереди, накопленное время выполнения, интенсивность обращения к операциям ввода/вывода. Вся эта информация должна сохраняться в соответствующих структурах данных.

В итоге, планировщик включается в работу при возникновении одного из следующих событий:

  • завершение кванта времени для текущего активного потока (сигнал от системного таймера);
  • нормальное завершение кода текущего активного потока;
  • аварийное завершение кода текущего активного потока;
  • запрос активным потоком занятого системного ресурса;
  • появление среди готовых потоков более приоритетного потока.
При этом запускается код планировщика, который просматривает приоритетные очереди и выбирает наиболее приоритетный поток. После этого происходит собственно само переключение потоков:
  • формируется контекст прерываемого потока;
  • с помощью контекста вновь активизируемого потока восстанавливается необходимое состояние вычислительной системы, в частности, загружаются необходимые значения во все регистры процессора;
  • поскольку в регистр-счетчик команд из контекста заносится адрес очередной подлежащей выполнению команды активизируемого потока, то процессор переходит к выполнению кода нового потока точно с того места, где оно было прервано.
Планирование потоков в системах реального времени строится на других принципах. Поскольку для подобных систем наиболее важным показателем является скорость работы, то планирование выполняется статически. Для этого заранее строится так называемая таблица переключений, с помощью которой в зависимости от текущего состояния вычислительного процесса быстро и однозначно определяется запускаемый в данный момент поток.

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

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

Сразу уточним, что все они, разумеется, поддерживают многопоточное скачивание и докачку файлов после обрыва связи и автоматически подбирают оптимальную (в зависимости от типа соединений) скорость скачивания. А также интегрируются в популярные браузеры, заменяя стандартный модуль закачки, и следят за буфером обмена, самостоятельно выявляя ссылки. А значит, в целом любое из названных решений обеспечивает быстрое и надежное скачивание файлов с FTP- и HTTP-серверов.

Между собой менеджеры закачки различаются разнообразными нюансами (см. таблицу). В частности, не все они обеспечивают частичное скачивание ZIP-архивов, корректно распознают ссылки с файлохранилищ, таких как Rapidshare в бесплатном режиме, и позволяют напрямую (то есть просто добавив URL вида http://www.youtube.com/watch?v=...) скачивать клипы с онлайновых видеосервисов3 (YouTube, Google Video и др.). Не все download-менеджеры умеют производить скачивание с защищенных FTP- и веб-серверов (то есть по протоколам SFTP и HTTPS соответственно) и позволяют оценить размер файла перед его загрузкой. А уж поддержка BitTorrent- и eDonkey-клиентов вообще реализована лишь в некоторых менеджерах загрузки, что, впрочем, на наш взгляд, уже не столь актуально, поскольку функциональность подобных клиентов невелика. В различных решениях разные списки поддерживаемых интернет-браузеров, да и сам принцип подобной интеграции различен: где-то достаточно просто включить соответствующие флажки в настройках, а где-то потребуется предварительно скачать и установить соответствующий браузеру плагин. Кроме того, имеются и более тонкие различия, касающиеся самого процесса закачки, - например в одних решениях при обнаружении активности браузера приоритет по трафику автоматически изменяется (а где-то это придется делать вручную), в других можно назначать закачкам приоритеты (что в части продуктов не предусмотрено) и т.п.

GetRight/GetRight Pro 6.3e

Разработчик : Headlight Software

Размер дистрибутива: GetRight - 4,78 Мбайт; GetRight Pro - 4,91 Мбайт

Работа под управлением: Windows 95/98/Me/NT/2000/XP/Vista

Способ распространения: shareware (30-дневная демо-версия: GetRight - http://download.getright.com/getright-download.exe ; GetRight Pro - http://download.getright.com/getright_pro_setup.exe)

Цена : GetRight - 19,95 долл.; GetRight Pro - 49,95 долл.

GetRight - давно присутствующий на рынке и завоевавший популярность благодаря удобству и надежной работе менеджер закачки, который сегодня уже далеко не столь привлекателен для широкого круга пользователей, поскольку по ряду параметров уступает аналогам и предлагается по весьма высокой цене. Да и дальнейшая разработка этого решения, по сути, уже не ведется. Данный download-менеджер позволяет скачивать файлы (в том числе по расписанию) по протоколам HTTP, HTTPS, FTP и FTPS и может использоваться для скачивания файлов с файлообменных серверов, получения новых музыкальных клипов в Podcast/RSS-канал и скачивания файлов по протоколу BitTorrent (имеется возможность одновременного получения части данных по FTP/HTTP, а части - из BitTorrent с последующим «склеиванием» на лету). Предусмотрена возможность автоматического добавления полученных мультимедиафайлов в плейлисты приложений MediaPlayer и iTunes. Однако утилита не поможет при скачивании видео с видеохостингов и частичном скачивании архивов.

GetRight автоматически интегрируется в ведущие браузеры, причем указать перечень интересующих браузеров можно при установке утилиты. Специальный встроенный обозреватель обеспечивает просмотр структуры папок FTP-серверов и HTTP-сайтов. Ограничение трафика производится вручную путем установки максимально допустимого предела скорости закачки, при этом разрешается включить флажок для снятия этого ограничения в моменты активности скринсейвера. Перед скачиванием можно проверить интересующий адрес на существование и уточнить размер файла. Количество одновременно скачиваемых файлов и число потоков регулируются, а лучшие «зеркала» для скачивания несложно найти автоматически либо указать вручную. В зависимости от типов закачиваемые файлы могут распределяться по разным папкам, для папок разрешается устанавливать приоритеты. По завершении закачки возможно автоматическое проведение оценки целостности полученных файлов и проверки их на вирусы.

Программа представлена в двух версиях - базовой GetRight и расширенной GetRight Pro. В Pro-версии предусмотрена возможность работы в режиме «клиент-сервер» (для скачивания файлов одним компьютером в сети, которому с остальных просто передаются ссылки) и в качестве прокси-сервера (позволяет другим интернет-утилитам использовать возможности GetRight по докачке файлов). В нее также встроен функционал для синхронизации уже скачанных файлов в случае появления на серверах их обновлений и закачки файлов на серверы, имеется скриптовый язык (обеспечивает расширенные возможности управления скачиванием), можно лимитировать скорость скачивания отдельных файлов и др.

Download Master 5.5.12.1171

Разработчик: WestByte Software

Размер дистрибутива: стандартная версия - 5,24 Мбайт; версия Portable - 3,7 Мбайт

Работа под управлением: Windows 95/98/Me/NT 4.0/2000/XP/Vista

Способ распространения: freeware (http://www.westbyte.com/dm/index.phtml?page=download&lng=Russian)

Цена: бесплатно

Download Master - многофункциональный download-менеджер, позволяющий загружать файлы не только с FTP- и HTTP-серверов, но также с популярных видеосервисов (YouTube, Google Video, RuTube, Видео@mail.?ru, Rambler Vision) и файлохранилищ (включая Rapidshare) в бесплатном режиме. В случае ZIP-архивов их содержимое может просматриваться перед закачкой, предусмотрена также возможность закачки только выбранных из архива файлов. Реализован поиск файлов, программ, игр и музыки в каталоге файлов TopDownloads.

Download Master интегрируется во все самые популярные браузеры (для клонов IE потребуется настройка параметров), а встроенный в утилиту FTP Explorer обеспечивает удобную навигацию по FTP-серверам. Утилита умеет самостоятельно определять типы загружаемых файлов и распределяет их по категориям (программы, музыка, видео и пр.), а при снижении скорости автоматически перезапускает закачку, что позволяет избежать простоев. Скачивание ведется в несколько потоков. При необходимости для определенных сайтов число потоков несложно ограничить и настроить программу так, чтобы скачиваемые с них файлы сохранялись в определенных папках и/или категориях. По окончании скачивания возможно отключение от Интернета, переход в спящий режим, выключение компьютера и т.п. Предусмотрено управление скоростью закачки и автоматическое ее снижение в случае, если пользователь занялся интернет-серфингом. Возможна работа по расписанию, а также проверка закачанных файлов на обновление и синхронизация (автообновление) файлов на сервере и локальном ПК.

Программа представлена в двух версиях: стандартной Download Master и портативной Download Master Portable. Последняя не требует установки и может быть записана на флэшку или внешний диск, что обеспечивает возможность скачивания файлов на любом подключенном к Интернету компьютере. В версии Portable нет интеграции с браузерами и отключена возможность экспорта/импорта настроек, поэтому для применения на собственном компьютере более удобной будет стандартная версия программы.

ReGet Deluxe 5.2

Разработчик: ReGet Software

Размер дистрибутива: ReGet Deluxe - 2,5 Мбайт; ReGet Deluxe Personal - 2 Мбайт

Работа под управлением: Windows 2000(SP3/SP4)/XP(SP2)/Server 2003/Vista

Способ распространения: shareware (30-дневная демо-версия: ReGet Deluxe - http://download.reget.com/regetdx.exe ; ReGet Deluxe Personal - http://download.reget.com/regetdxpers.exe)

Цена: ReGet Deluxe - 600 руб; ReGet Deluxe Personal - бесплатно (только для домашнего применения)

ReGet Deluxe - многофункциональный менеджер закачек, позволяющий загружать файлы (в том числе по расписанию) не только с обычных FTP- и HTTP-серверов, но и с защищенных файловых (SFTP) и веб (HTTPS)-серверов. Также утилита умеет скачивать мультимедиаконтент через потоковые протоколы (MMS, RTSP) и может использоваться для скачивания с файлообменных серверов (MySpace.com, iDrive.com и т.д.), однако она не поможет скачать флэш-видео с видеохостингов, в частности с YouTube. Утилита отображает размер скачиваемого файла еще перед закачкой, позволяет просматривать ZIP-архивы и скачивать их частично и умеет автоматически переключаться на более быстрые «зеркала».

ReGet Deluxe автоматически интегрируется в Internet Explorer и ряд его клонов, интеграция в часть браузеров осуществляется через плагины сторонних разработчиков. Встроенный FTP-браузер упрощает поиск нужных файлов на FTP-серверах. Загружаемые файлы могут автоматически раскладываться по разным папкам с учетом назначенной им пользователем категории, причем при использовании макросов допускается даже автоматическое создание нужных папок в соответствии с расширениями скачанных файлов, датой загрузки или именем сервера, с которого был скачан файл. При замедлении конкретной закачки утилита автоматически отключается от сервера и соединяется с ним снова, давая закачке стартовый толчок. Одновременно может загружаться несколько файлов - их количество (как и число потоков) зависит от типа соединения. В ходе скачивания утилита замечает активность браузера и автоматически понижает свой трафик при передаче браузером данных. По завершении скачивания она может автоматически разорвать интернет-соединение, запустить внешнее приложение, выключить компьютер и т.п.

Программа представлена в двух редакциях: ReGet Deluxe и ReGet Deluxe Personal, последняя не имеет мультиязычной поддержки и предназначена для использования только на домашнем компьютере. Утилита может работать в одном из трех режимов: упрощенном (в нем работают лишь базовые функции), расширенном и режиме эксперта, переключение между ними осуществляется при помощи команд главного меню.

Free Download Manager 3.0 build 848

Разработчик : Free Download Manager.ORG

Размер дистрибутива: 6,39 Мбайт

Работа под управлением: Windows 9x/Me/2000/2003/XP/Vista (только 32-битные версии)

Способ распространения: freeware (http://freedownloadmanager.org/download.htm)

Цена: бесплатно

Free Download Manager - полноценный и очень удобный менеджер закачки, позволяющий загружать файлы (в том числе по расписанию) с FTP- и HTTP-серверов, защищенных веб (HTTPS)-серверов, а также с популярных файлохранилищ и видеосервисов (YouTube, Google Video и др.). Возможна одновременная разгрузка от нескольких «зеркал». При скачивании видеоконтента допускается автоматическое преобразование FLV-файлов в другие видеоформаты с помощью встроенного перекодировщика видео. Предусмотрена частичная загрузка ZIP-архивов, скачивание файлов через сеть BitTorrent и целиком сайтов для их последующего просмотра в офлайне. Имеется также специальный Upload manager, обеспечивающий загрузку файлов в онлайновое хранилище WikiFortio (http://www.wikifortio.com/), где разрешается до месяца хранить файлы размером до 100 Мбайт.

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

Программа представлена в двух редакциях: стандартной Free Download Manager и облегченной Free Download Manager Lite. В последней нет поддержки протокола BitTorrent, а также отсутствуют встроенный видеоконвертор и менеджер закачки файлов на серверы. В обеих редакциях есть функционал для записи портативной версии, которая не требует установки и может быть записана на флэшку или внешний диск.

Orbit Downloader 2.8.13

Разработчик: OrbitDownloader

Размер дистрибутива: 2,17 Мбайт

Работа под управлением: Windows NT/2000/XP/2003/Vista

Способ распространения: freeware (http://www.orbitdownloader.com/download.htm)

Цена: бесплатно

Orbit Downloader - очень простой в применении, но достаточно функциональный и удобный менеджер закачки, отличающийся расширенной поддержкой социальных сервисов. Он позволяет загружать не только файлы по протоколам FTP и HTTP, но и разного рода потоковый флэш-, видео- и аудиоконтент через протоколы RTSP/MMS/RTMP с MySpace, YouTube, Imeem, Pandora и других подобных сервисов. Возможна загрузка файлов с файлообменных сервисов (включая Rapidshare, MegaUpload, 4shared, Depositfiles и пр.), а также проведение загрузки по технологии Metalink, позволяющей скачивать отдельные сегменты из сетей практически с любым протоколом. Скачивание медиаконтента с социальных сервисов реализовано в этой утилите через встроенный модуль Grab++, работающий только под Internet Explorer. Причем технология скачивания принципиально отличается от принятой в других download-менеджерах: если обычно менеджеру загрузки принято просто указывать ссылку вида http://www.youtube.com/watch?v=.., то модуль Grab++ определяет прямую ссылку при наведении указателя мыши на нужный ролик в окне его просмотра.

Программа интегрируется в популярные браузеры, причем поддержка нужных браузеров настраивается уже в ходе ее установки. Ограничение трафика производится вручную через настройки. Одновременно могут скачиваться несколько файлов - каждый в несколько потоков, число потоков регулируется, можно также изменить количество потоков для отдельно взятой закачки. Уточнить размер файла перед закачкой невозможно, равно как и частично скачать ZIP-архив, но разрешается просматривать содержимое ZIP-файла до его скачивания. Увеличение скорости закачки достигается не только за счет многопоточности, но и благодаря использованию технологии Orbitnet, базирующейся на Р2Р и автопоиске «зеркал». Уже закачанные файлы несложно перераспределить по разным папкам. По завершении скачивания утилита может проверить файл на вирусы встроенным антивирусом, автоматически разорвать интернет-соединение и выключить компьютер.

FlashGet 1.9.6

Разработчик : Trend Media Corporation Ltd

Размер дистрибутива: 4,43 Мбайт

Работа под управлением: Windows (все версии)

Способ распространения: freeware (http://www.flashget.com/en/download.htm?uid=undefined)

Цена: бесплатно

FlashGet - наверное, самый популярный в мире менеджер закачки файлов с наибольшей историей развития. Сегодня эта утилита по-прежнему достойна внимания благодаря удобству, простоте использования и высокой скорости скачивания, однако ее функционал устроит не всех пользователей, поскольку в большинстве своем он ограничен лишь базовыми возможностями. FlashGet позволяет скачивать файлы по протоколам HTTP/FTP/MMS/RTSP и вполне корректно распознает ссылки с Rapidshare. Однако в целом при работе с файловыми хостингами могут быть проблемы, а скачивание видео с видеохостингов вообще невозможно, равно как и частичная закачка ZIP-архивов. Вместе с тем в последней версии утилиты появилась возможность скачивания по протоколам BitTorrent и eMule, что предусмотрено далеко не в каждом download-менеджере.

FlashGet умеет интегрироваться в популярные браузеры, поддержка части из которых требует установки плагинов. Встроенные FTP- и HTTP-обозреватели упрощают поиск нужных файлов. Оптимальная скорость соединения указывается в настройках путем установки типа соединения, возможна установка ограничения трафика вручную выбором одного из трех предустановленных режимов. Скачиваемые файлы могут распределяться по разным папкам с учетом указанных пользователем категорий. Предусмотрен автоматический поиск «зеркал» и осуществление загрузки с самых быстрых и доступных серверов. Несложно настроить проведение скачивания в строго назначенное время, а по его завершении утилита может проверить файлы на вирусы и разорвать соединение.

ReGet Junior 2.2

Разработчик: ReGet Software

Размер дистрибутива: 1,66 Мбайт

Работа под управлением: Windows 95/98/Me/NT/2000/XP

Способ распространения: shareware (30-дневная демо-версия - http://download.reget.com/regetjr.exe)

Цена: 250 руб.

ReGet Junior - самый простой в применении download-менеджер, ориентированный на начинающих пользователей. Утилита обладает минимальным функционалом, и ее привлекательность заключается лишь в том, что разбираться с настройками не потребуется в принципе. Она позволяет загружать файлы с FTP- и HTTP-серверов и интегрируется в наиболее популярные браузеры. Скачивание ведется в несколько потоков, и одновременно могут загружаться несколько файлов; число потоков и одновременно скачиваемых файлов не регулируется.

Заключение

Итак, функционал download-менеджеров от разных разработчиков весьма схож - все они обеспечивают надежную и быструю закачку файлов из Сети. Поэтому многим домашним пользователям, работающим в наиболее популярных под Windows браузерах, вполне достаточно обзавестись для решения данной задачи одним бесплатным инструментом, например Download Master, Free Download Manager, ReGet Deluxe (в редакции Personal) или Orbit Downloader. Теоретически все они умеют скачивать разного рода информацию, включая файлы с серверов типа Rapidshare.com и, за исключением ReGet Deluxe, потоковый флэш-, видео- и аудиоконтент с YouTube и прочих социальных сервисов. Однако возможность захвата видео и flash наиболее полно реализована в Orbit Downloader, на который и стоит обратить внимание любителям закачки такого рода контента. Что касается FlashGet, то делать ставку на него, на наш взгляд, особого смысла не имеет в силу уступающей вышеназванным программам функциональности.

Выбор пользователей Google Chrome и Apple Safari скромнее - им придется воспользоваться Download Master, Free Download Manager или Orbit Downloader, поскольку в других рассмотренных download-менеджерах поддержка соответствующих браузеров отсутствует. При этом нужно иметь в виду, что закачкой медиаконтента с социальных сервисов в Orbit Downloader им воспользоваться не удастся, поскольку она работает только под Internet Explorer.