Шедулер что это такое
Перейти к содержимому

Шедулер что это такое

  • автор:

Что такое Task Scheduler?

Сервис Task Scheduler (Планировщик задач) — это программа, которая запускает другие программы в зависимости от различных условий или критериев, используемая в системах семейства Windows.

Заявка на хостинг
Провайдеры сами пришлют
вам свои предложения 😉

3 Гб на диске, неогр. трафик.

Проверка IP

Ваш IP . 95.214.216.82 ← Проверить
Страна . Испания

Проверка домена (+whois)

Расширенный поиск (более 50 зон)

Traceroute

Акции провайдеров

Постоянные акции от HyperHost!
HyperHost

Класс Scheduler

Представляет абстракцию для планировщика среды выполнения с параллелизмом.

Синтаксис

class Scheduler; 

Участники

Защищенные конструкторы

Имя Описание
Планировщик Объект Scheduler класса может создаваться только с помощью методов фабрики или неявно.
~Планировщик деструктор Объект Scheduler класса неявно уничтожается, когда все внешние ссылки на него перестают существовать.

Открытые методы

Имя Описание
Присоединить Присоединяет планировщик к контексту вызова. После возвращения этого метода вызывающий контекст управляется планировщиком, а планировщик становится текущим планировщиком.
Создание Создает новый планировщик, поведение которого описано _Policy параметром, помещает начальную ссылку на планировщик и возвращает указатель на него.
CreateScheduleGroup Перегружен. Создает новую группу расписаний в планировщике. Версия, которая принимает параметр _Placement , приводит к тому, что задачи в созданной группе расписаний будут предвзяты в сторону выполнения в расположении, указанном этим параметром.
GetNumberOfVirtualProcessors Возвращает текущее количество виртуальных процессоров для планировщика.
GetPolicy Возвращает копию политики, с помощью которую был создан планировщик.
Id Возвращает уникальный идентификатор планировщика.
IsAvailableLocation Определяет, доступно ли данное расположение на планировщике.
Ссылка Увеличивает число ссылок планировщика.
RegisterShutdownEvent Вызывает передачу дескриптора событий Windows в _Event параметре при завершении работы планировщика и его уничтожении. В то время, когда событие сигнализирует, все работы, запланированные планировщику, завершены. С помощью этого метода можно зарегистрировать несколько событий завершения работы.
Выпуск Уменьшает значение счетчика ссылок планировщика.
ResetDefaultSchedulerPolicy Сбрасывает политику планировщика по умолчанию в среду выполнения по умолчанию. При следующем создании планировщика по умолчанию он будет использовать параметры политики по умолчанию во время выполнения.
ScheduleTask Перегружен. Планирует задачу с легким весом в планировщике. Упрощенная задача будет размещена в группе расписаний, определенной средой выполнения. Версия, принимающая параметр _Placement , склоняет задачу к выполнению в указанном расположении.
SetDefaultSchedulerPolicy Позволяет использовать определяемую пользователем политику для создания планировщика по умолчанию. Этот метод можно вызывать только в том случае, если планировщик по умолчанию не существует в процессе. После установки политики по умолчанию он остается в силе до следующего допустимого вызова SetDefaultSchedulerPolicy метода ResetDefaultSchedulerPolicy .

Замечания

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

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

Иерархия наследования

Требования

Заголовок: concrt.h

Пространство имен: concurrency

Attach

Присоединяет планировщик к контексту вызова. После возвращения этого метода вызывающий контекст управляется планировщиком, а планировщик становится текущим планировщиком.

virtual void Attach() = 0; 

Замечания

Присоединение планировщика неявно помещает ссылку на планировщик.

В будущем необходимо вызвать метод CurrentScheduler::D etach , чтобы разрешить планировщику завершить работу.

Если этот метод вызывается из контекста, который уже подключен к другому планировщику, существующий планировщик запоминается как предыдущий планировщик, а созданный планировщик становится текущим планировщиком. При вызове CurrentScheduler::Detach метода в более позднюю точку предыдущий планировщик восстанавливается в качестве текущего планировщика.

Этот метод вызовет исключение improper_scheduler_attach , если этот планировщик является текущим планировщиком контекста вызова.

Создание

Создает новый планировщик, поведение которого описано _Policy параметром, помещает начальную ссылку на планировщик и возвращает указатель на него.

static Scheduler* __cdecl Create(const SchedulerPolicy& _Policy); 

Параметры

_Политики
Политика планировщика, описывающая поведение только что созданного планировщика.

Возвращаемое значение

Указатель на только что созданный планировщик. Этот Scheduler объект имеет начальное число ссылок, помещенное на него.

Замечания

После создания планировщика с Create помощью метода необходимо вызвать Release метод в какой-то момент в будущем, чтобы удалить начальное число ссылок и разрешить планировщику завершить работу.

Планировщик, созданный с помощью этого метода, не подключен к контексту вызова. Его можно подключить к контексту с помощью метода Attach .

CreateScheduleGroup

Создает новую группу расписаний в планировщике. Версия, которая принимает параметр _Placement , приводит к тому, что задачи в созданной группе расписаний будут предвзяты в сторону выполнения в расположении, указанном этим параметром.

virtual ScheduleGroup* CreateScheduleGroup() = 0; virtual ScheduleGroup* CreateScheduleGroup(location& _Placement) = 0; 

Параметры

_Размещения
Ссылка на расположение, в котором задачи в группе расписаний будут предвзяты к выполнению.

Возвращаемое значение

Указатель на только что созданную группу расписаний. Этот ScheduleGroup объект имеет начальное число ссылок, помещенное на него.

Замечания

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

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

GetNumberOfVirtualProcessors

Возвращает текущее количество виртуальных процессоров для планировщика.

virtual unsigned int GetNumberOfVirtualProcessors() const = 0; 

Возвращаемое значение

Текущее число виртуальных процессоров для планировщика.

GetPolicy

Возвращает копию политики, с помощью которую был создан планировщик.

virtual SchedulerPolicy GetPolicy() const = 0; 

Возвращаемое значение

Копия политики, с помощью которую был создан планировщик.

Артикул

Возвращает уникальный идентификатор планировщика.

virtual unsigned int Id() const = 0; 

Возвращаемое значение

Уникальный идентификатор планировщика.

IsAvailableLocation

Определяет, доступно ли данное расположение на планировщике.

virtual bool IsAvailableLocation(const location& _Placement) const = 0; 

Параметры

_Размещения
Ссылка на расположение для запроса планировщика.

Возвращаемое значение

Указание того, доступно ли расположение, указанное _Placement аргументом, на планировщике.

Замечания

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

Ссылка

Увеличивает число ссылок планировщика.

virtual unsigned int Reference() = 0 ; 

Возвращаемое значение

Новое добавочное число ссылок.

Замечания

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

Метод вызывает исключение improper_scheduler_reference , если число ссылок до вызова Reference метода было равно нулю, и вызов выполняется из контекста, который не принадлежит планировщику.

RegisterShutdownEvent

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

virtual void RegisterShutdownEvent(HANDLE _Event) = 0; 

Параметры

_Событие
Дескриптор объекта события Windows, который будет сигнализировать среде выполнения при завершении работы планировщика и его уничтожении.

Выпуск

Уменьшает значение счетчика ссылок планировщика.

virtual unsigned int Release() = 0; 

Возвращаемое значение

Только что отложенное число ссылок.

Замечания

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

ResetDefaultSchedulerPolicy

Сбрасывает политику планировщика по умолчанию в среду выполнения по умолчанию. При следующем создании планировщика по умолчанию он будет использовать параметры политики по умолчанию во время выполнения.

static void __cdecl ResetDefaultSchedulerPolicy(); 

Замечания

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

Планировщик

Объект Scheduler класса может создаваться только с помощью методов фабрики или неявно.

Scheduler(); 

Замечания

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

Вы также можете явно создать планировщик с помощью CurrentScheduler::Create метода или Scheduler::Create метода.

~Планировщик

Объект Scheduler класса неявно уничтожается, когда все внешние ссылки на него перестают существовать.

virtual ~Scheduler(); 

ScheduleTask

Планирует задачу с легким весом в планировщике. Упрощенная задача будет размещена в группе расписаний, определенной средой выполнения. Версия, принимающая параметр _Placement , склоняет задачу к выполнению в указанном расположении.

virtual void ScheduleTask( TaskProc _Proc, _Inout_opt_ void* _Data) = 0; virtual void ScheduleTask( TaskProc _Proc, _Inout_opt_ void* _Data, location& _Placement) = 0; 

Параметры

_Proc
Указатель на функцию, выполняемую для выполнения задачи легкого веса.

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

_Размещения
Ссылка на расположение, где будет склонна выполняться упрощенная задача.

SetDefaultSchedulerPolicy

Позволяет использовать определяемую пользователем политику для создания планировщика по умолчанию. Этот метод можно вызывать только в том случае, если планировщик по умолчанию не существует в процессе. После установки политики по умолчанию он остается в силе до следующего допустимого вызова SetDefaultSchedulerPolicy метода ResetDefaultSchedulerPolicy .

static void __cdecl SetDefaultSchedulerPolicy(const SchedulerPolicy& _Policy); 

Параметры

_Политики
Политика, заданная в качестве политики планировщика по умолчанию.

Замечания

SetDefaultSchedulerPolicy Если метод вызывается, когда планировщик по умолчанию уже существует в процессе, среда выполнения вызовет исключение default_scheduler_exists.

Что такое планировщик встреч и чем он может быть полезен для вашего бизнеса

Что такое планировщик встреч и чем он может быть полезен для вашего бизнеса

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

И я такой не один. Только у меня наберется с десяток знакомых с аналогичной болью на душе, не говоря уже о том, какой сегмент бизнеса в РФ безуспешно пытается избавиться от тех же проблем и продолжает страдать.

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

Но у меня и моей команды Makemeet есть предложение на этот счет.

Что такое планировщик встреч и что он умеет

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

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

Шедулер

А шедулер – решение для всех, в котором каждый может создать собственное расписание без всяких CRM. Достаточно сообщить приложению, в какое время вы готовы планировать встречи. После этого программа создаст интерфейс, через который к вам «на прием» смогут записаться все пользователи, со ссылкой на ваше расписание.

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

Комьюнити теперь в Телеграм
Подпишитесь и будьте в курсе последних IT-новостей

Популярные шедулеры и их особенности

Отказ от переписки по почте и переход на планировщик встреч благоприятно сказывается на бизнесе, поэтому подобные сервисы начали расти (в количественном отношении) как грибы. На западе активно используют приложения Calendly, Bookafy, ScheduleOnce, SimplyBook и десятки их аналогов.

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

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

Calendly

В Calendly есть весь базовый набор опций, типичных для шедулеров: ограничение количества свободных временных ячеек, оповещения о новых записях по почте и push-уведомления. Но самое главное – огромное количество интеграций со сторонними службами и программами, включая Teams, Zoom, iCloud, Google Calendar, Slack, PayPal и другие.

Далее будем рассматривать шедулеры на примере Calendly, так как это наиболее конкурентоспособный продукт в своей категории.

Как используют планировщики встреч? 5 примеров

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

Пример La-Z-Boy

Популярный в США мебельный бренд La-Z-Boy из-за коронавирусных ограничений был вынужден закрыть магазины и искать способ взаимодействия с клиентами удаленно. Выходом стали индивидуальные онлайн-экскурсии для клиентов с гидом-дизайнером, который мог бы показать товар, рассказать о нем, подобрать сопутствующую мебель и аксессуары.

Услуга стала на удивления популярной, и La-Z-Boy столкнулся с неожиданно большим потоком пользователей. Они задействовали Calendly и создали в программе 60 ячеек для 60 потенциальных гостей соответственно. Благодаря возможностям, простоте и эффективности приложения магазин за 2 месяца увеличил эту цифру до 410 «слотов».

В России виртуальные экскурсии проводят в сфере недвижимости при продаже и сдаче квартир в аренду. Торговая площадка Авито дает подобную возможность, правда, на совсем базовом уровне, предлагая пользователям самим выяснить время встречи и программу для общения.

Авито встреча

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

Даже если интерфейс Авито или любой другой площадки не предлагает возможности оставить ссылку на Calendly или его аналог, можно отправить ее через СМС или мессенджеры в духе WhatsApp.

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

Пример Ancestry.com

У сервиса по составлению генеалогического древа Ancestry была ситуация, похожая на ту, с которой столкнулся бренд La-Z-Boy. В какой-то момент приток пользователей, желающих воспользоваться сервисом, вырос настолько, что сотрудники, общающиеся с клиентами, перестали успевать обрабатывать все заявки.

Использование планировщика встреч

С появлением Calendly этап общения менеджера и клиента почти выпал из рабочего процесса Ancestry. Все желающие воспользоваться услугами сервиса сами записывались через интерфейс Calendly – люди выбирали удобное для себя время и в пару кликов «записывались на встречу» с сотрудниками Ancestry без участия менеджеров.

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

Планировщик встреч бы исключил этот отнимающий впустую время этап взаимодействия с клиентом.

Пример Signpost

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

Сотрудники Signpost знали, что теряют деньги. Слишком много «горячих» лидов превращались в «холодные» на глазах у «эффективных» менеджеров компании.

Signpost

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

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

Вместо того чтобы списываться с кандидатом на должность, ждать от него заполнения анкет и предоставления прочих данных, можно отправлять ему по почте или через СМС ссылку на интерфейс планировщика, где соискатель сам выберет время, когда ему будет удобно пообщаться с HR’ом.

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

Пример Bitly

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

Битли и Календли

Сначала руководство заставило менеджеров перейти на общение по электронной почте вместо телефона, а затем внедрила Calendly как основной способ бронирования встреч для потенциальных клиентов.

После этого у Bitly на 100% выросло количество демонстраций продуктов, на 40% увеличились продажи и почти 90% всех встреч в компании стали планироваться с помощью Calendly.

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

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

Пример College for Creative Studies

Сотрудники дизайнерской школы College for Creative Studies в Детройте на регулярной основе должны участвовать в различных мероприятиях, разъезжать по встречам, опрашивать бывших студентов и параллельно преподавать. При таком жестком графике планирование по телефону или электронной почте превращается во внушительного пожирателя времени, отнимающего несколько часов у и без того загруженного дня.

Одна из сотрудниц College for Creative Studies опробовала шедулеры. Первым был сервис Meetingbird, который справлялся с поставленной задачей, но не мог предложить дополнительные инструменты для автоматизации процесса назначения встреч.

Планировщик встреч Календли

С переходом на Calendly ситуация стала еще лучше, потому что специалисты College for Creative Studies перестали тратить время на поиски удобного расписания, начали встречаться с большим количество людей и опрашивать больше студентов.

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

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

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

Другие сценарии

Естественно, никто не запрещает использовать Calendly и другие похожие инструменты в повседневной жизни. Например, можно договориться о встрече с друзьями и отправить им ссылку на свое расписание в планировщике встреч, где они укажут время встречи, место и другие важные подробности грядущего мероприятия. И все это за пару кликов без необходимости несколько дней обмениваться сообщениями или письмами.

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

И таких бытовых сценариев применения может быть масса. Вы ограничены только собственной фантазией.

Есть ли шедулеры в России?

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

Планирование встреч, шедулер

Настройки форм в SimplyBook на русском языке

Поэтому в России пока никто толком не смог внедрить планировщики встреч в свой бизнес, а стоило бы.

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

Мы создаем свой планировщик встреч, адаптированный под российского пользователя

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

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

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

Приглашаем на закрытое бета-тестирование нашего нового продукта! Первые 100 пользователей, оставивших заявку, смогут пользоваться сервисом бесплатно.

От шедулера к планировщику

Сразу просьба к строгим читателям. Если вы не поняли какой-либо термин из применённых — спросите, я подскажу, что я имел в виду. А если вам нравится другое написание или перевод этого термина — укажите его в комментарии. Я применяю те, которые нравятся мне.

Итак, в прошлых статьях описан механизм реализации многозадачности за вычетом планировщика, он же шедулер, он же скедулер, он же Васька меченый, сорри, заговариваюсь я с этими терминами…

Как я уже говорил, шедулер — это просто функция, которая отвечает на вопрос: какую нить и на сколько времени поставить на процессор.

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

Говоря о шедулере нельзя не сказать о приоритетах.

Приоритет — свойство нити (или процесса) влияющее на конкуренцию этой нити с другими нитями за процессор.

Приоритет обычно описывается парой .

На сегодня сформировалась довольно чёткая схема реализации приоритетов. Приоритеты нитей делятся на три класса:

  • Реальное время: нити такого класса всегда вытесняют с процессора нити других классов так быстро, как это возможно, и никогда не снимаются с процессора кроме как по наличию нити с более высоким приоритетом реального времени. То есть — такие нити сами должны решать, когда им больше не нужен процессор.
  • Разделение времени: нити такого класса всегда вытесняют с процессора нити класса idle, между собой нити разделения времени конкурируют мягко. Две нити такого класса с разными значениями приоритета будут получать разный процент процессорного времени, но обязательно будут его получать, даже если значения приоритетов различаются предельным образом.
  • Idle класс: нити такого класса получают процессор только если нет готовых к исполнению нитей других классов, «на сдачу». Лично я не вижу смысла в значении приоритета внутри класса idle. Хотя так тоже бывает.

Кстати. Говорят, Кернигана как-то спросили, что бы он сделал иначе, если бы писал Юникс заново. «Написал бы creat как create», — ответил мэтр. Я бы добавил к списку исправлений ещё мешок несуразностей, начиная с nice — понятие приоритета в Юниксе почему-то первёрнуто. Чем nice меньше, тем приоритет выше.

Мы в данной статье будем придерживаться более человеколюбивой шкалы: выше численное значение = больше процессора.

Кому-то, наверное, уже хочется заглянуть в код. Вот он:
Исходный текст Фантомовского шедулера.

Тут мы немного играем в Пушкина 🙂

И вот уже трещат морозы
И серебрятся средь полей…
(Читатель ждет уж рифмы розы;
На, вот возьми ее скорей!)

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

За сим — продолжим.

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

Конкретно в Фантоме это три очереди, согласно классам:

/** Idle prio threads */ static queue_head_t runq_idle = ; /** Normal prio threads */ static queue_head_t runq_norm = ; /** Realtime prio threads */ static queue_head_t runq_rt = ; 

В целом нить по отношению к процессору может находиться в трёх состояниях:

  • Заблокирована. Не находится на процессоре, не может быть на него поставлена. Отсутствует в какой-либо run queue.
  • Исполняется. Отсутствует в какой-либо run queue.
  • Может исполняться. Присутствует в какой-либо run queue.

То есть, в run queue находятся нити, которые хотели бы попасть на процессор.

Отсюда работа планировщика сводится к тому, чтобы:

  1. Определиться с тем, нить какого класса приоритета сейчас будем запускать. Это просто — проверить, не пуста ли очередь realtime — если не пуста, то мы запускаем нить realtime, проверить очередь нормальных приоритетов — если не пуста, то запускаем нормальную нить. Иначе — запускаем idle нить. Если и таких нет, отмечаем, что процессор idle и уходим в нить «вечного» сна.
  2. Если определились с приоритетом — выбрать правильную нить для исполнения в данном приоритете.
  3. Назначить нити временной интервал для исполнения.

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

 // Have some realtime? if( !queue_empty(&runq_rt) ) < int maxprio = -1; phantom_thread_t *best = 0; phantom_thread_t *it = 0; queue_iterate(&runq_rt, it, phantom_thread_t *, runq_chain) < if( it->thread_flags & THREAD_FLAG_NOSCHEDULE ) continue; if( ((int)it->priority) > maxprio ) < maxprio = it->priority; best = it; > > if( best ) < assert(t_is_runnable(best)); return best; >> 

Очевидная доработка кода заключается в том, чтобы не сортировать все нити в шедулере, а вставлять нить в очередь в порядке убывания численного приоритета. Тогда планировщику достаточно просто вынуть из очереди первую нить и её запустить.

Теперь нити с приоритетом класса разделения времени — то есть, обычные нити, мягко конкурирующие за процессор.

Здесь надо отметить, что переменная ticks_left в структуре состояния нити определяет, сколько 10 мсек интервалов нить продержится на процессоре.

Сначала рассмотрим, что делает функция t_assign_time():

 it->ticks_left = NORM_TICKS + it->priority; 

Она проверяет, что все нити истратили свои ticks_left, и если да — назначает им новые ticks_left — тем, у кого приоритет больше — даёт больше процессорного времени.

Что делает сам планировщик? Выбирает нить с максимальным приоритетом и с ненулевым остатком процессорного времени, её и запускает:

 // Have normal one? if( !queue_empty(&runq_norm) ) < // If no normal thread has ticks left, reassign // ticks and retry do < unsigned int maxprio = 0; // NB! not a negative number! phantom_thread_t *best = 0; phantom_thread_t *it = 0; queue_iterate(&runq_norm, it, phantom_thread_t *, runq_chain) < if( it->thread_flags & THREAD_FLAG_NOSCHEDULE ) continue; if( (it->priority > maxprio) && (it->ticks_left > 0) ) < maxprio = it->priority; best = it; > > if( best ) < return best; >> while(t_assign_time()); > 

Когда все остатки у всех нитей кончились — просит t_assign_time() назначить нитям новые остатки.

Вообще-то, сортировка здесь относительно избыточна. Достаточно просто добавлять нити в конец очереди, а выбирать из начала — fair enough. Вообще, сортировать все нити — очевидно плохо, не делайте так. Я тоже этот кусок перепишу более оптимальным образом, например, так как уже описал выше, для realtime.

Кстати, при чтении кода планировщика надо учитывать, что нити не всегда «съедают» свой квант времени — нить может заблокироваться на примитиве синхронизации и часть времени простоять не по своей воле. Этим и обусловлена сортировка: если приоритет нити высок, то нить после разблокирования вернётся на процессор раньше, чем доработают все остальные нити.

Хорошо, перейдём к idle priority class. Мы попадём сюда только если в предыдущих классах все нити спят или отсутствуют.

 // Have idle one? ret = (phantom_thread_t *)queue_first(&runq_idle); if( ret ) < if( ret->thread_flags & THREAD_FLAG_NOSCHEDULE ) goto idle_retry; // Just take first. Switched off thread will become // last on runq, so all idle threads will run in cycle ret->ticks_left = NORM_TICKS; return ret; > else goto idle_no; 

Здесь всё просто — берём первую попавшуюся, запускаем на стандартное время. Поскольку при снятии с процессора она попадёт в конец очереди runq_idle, все такие нити будут запускаться по кругу.

Наконец, если вообще ничего не нашлось, у нас есть специальная idlest thread на этот случай.

 STAT_INC_CNT(STAT_CNT_THREAD_IDLE); percpu_idle_status[GET_CPU_ID()] = 1; // idle return GET_IDLEST_THREAD(); // No real thread is ready to run 

Она у каждого процессора своя просто потому, что одну нить нельзя запустить дважды. Проста как мычание:

 while(1)

Что здесь не учтено.

Interactive thread prio boost: обычно планировщики увеличивают фактический приоритет нитям, которые замечены во вводе-выводе с консоли или другой сущности, за которой, потенциально, прячется интерактивный юзер. Это повышает перцептивную реактивность системы — «операционка меньше тупит» с точки зрения человека. И наоборот — если нить «доедает» свой таймслайс до конца, и делает это стабильно, ей немного понижают приоритет, считая её чисто вычислительной. С той же целью — повысить реактивность системы.

Это, конечно, касается только нитей с обычным классом приоритетов — никто и никогда не трогает приоритеты реального времени.

Планирование реального времени с гарантией доли процессора. Строгие системы реального времени имеют жёсткий план, в рамках которого нить или группа нитей может получать чётко оговоренное количество процессорного времени.

Инверсия приоритетов.

Предположим, у нас есть страшно важная нить R с максимальным приоритетом реального времени, и нить I с приоритетом класса idle, которая занимается несущественной ерундой. А так же обычная нить U, которая работает с юзером — читает команды с консоли. Шелл, например.

Юзер бездействует, ждёт ввода-вывода и нить U.

Нить I получает процессор, решает поделать свою ерунду и хочет для этого выделить себе немного памяти. Функция выделения памяти ядра запирает глобальный мьютекс и начинает выделять. Работая на idle prio, очевидно.

В этот момент просыпается ото сна нить R, которой пора скорректировать положение стержня поглотителя активной зоны реактора. И тоже хочет немного памяти.

(Давайте не будем привередничать и спрашивать, что U и R делают на одной машине — U может быть сервером статистики по TCP, например.)

Естественно, R забирает процессор у I, но упирается в глобальный мьютекс при выделении памяти, и останавливается.

Тут бы I продолжить работу, но юзер набирает команду, и U принимается за работу, отбирая процессор у I. Теперь, внезапно, высокоприоритетная нить реального времени R ждёт окончания работы нити U, и реактор взрывается к чертям.

Для того, чтобы это не случалось, делают то, что у меня в Фантоме пока не сделано — инверсию приоритетов.

Она формулируется так: если нить более высокого приоритета заблокирована на ресурсе, занятом нитью низкого приоритета, вторая нить получает на время такой блокировки приоритет первой нити.

То есть, в нашем примере, нить I на время блокировки мьютекса выделения памяти должна была получить приоритет реального времени от нити R, вытеснить к чертям нить U и доделать то, что блокирует нить R. После разблокировки мьютекса её приоритет должен понизиться обратно до idle и процессор перейдёт к R, как и должно быть.

Вот теперь, наверное, всё. 🙂

  • Системное программирование
  • Программирование микроконтроллеров

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *