Контексты

В этом документе описывается роль контекстов в Concurrency Runtime. Поток, подключенный к планировщику, называется контекстом выполнения или просто контекстом. Функция concurrency::wait и класс concurrency::Context позволяют управлять поведением контекстов. Используйте функцию wait для приостановки текущего контекста в течение указанного времени. Используйте класс Context, когда требуется больше контроля над тем, когда контексты блокируют, разблокируют и приостанавливают выполнение, или для перегрузки текущего контекста.

Совет

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

Функция ожидания

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

Передача 0 (ноль) для milliseconds параметра приводит к приостановке текущего контекста до тех пор, пока все другие активные контексты не получат возможность выполнять работу. Это позволяет передать управление всем другим активным задачам.

Пример

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

Класс Context

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

Совместная блокировка

Класс Context позволяет блокировать или давать текущий контекст выполнения. Блокировка или уступка полезны, если текущий контекст не может продолжаться, потому что ресурс недоступен.

Метод конкуррентности::Context::Block блокирует текущий контекст. Заблокированный контекст освобождает свои ресурсы обработки, чтобы среда выполнения могла выполнять другие задачи. Метод concurrency::Context::Unblock разблокирует заблокированный контекст. Метод Context::Unblock должен вызываться из другого контекста, отличного от вызываемого Context::Block. Среда выполнения вызывает конкурентность::context_self_unblock, если контекст пытается разблокировать себя.

Для кооперативного блокирования и разблокировки контекста обычно вызывается concurrency::Context::CurrentContext, чтобы получить указатель на Context объект, связанный с текущим потоком, и сохранить результат. Затем вызывается Context::Block метод для блокировки текущего контекста. Позже вызовите Context::Unblock из отдельного контекста, чтобы разблокировать заблокированный контекст.

Необходимо сопоставить каждую пару вызовов Context::Block и Context::Unblock. Среда выполнения вызывает конкуренция::context_unblock_unbalanced, когда метод Context::Block или Context::Unblock вызывается последовательно без соответствующего вызова другого метода. Однако, не обязательно вызывать Context::Block перед вызовом Context::Unblock. Например, если один контекст вызывает Context::Unblock перед тем, как другой контекст вызывает Context::Block для того же контекста, то этот контекст остается разблокированным.

Метод concurrency::Context::Yield дает выполнение, чтобы среда выполнения могли выполнять другие задачи, а затем перепланировать контекст для выполнения. При вызове метода Context::Block среда выполнения не перепланирует контекст.

Пример

Пример, использующий методы Context::Block, Context::Unblock и Context::Yield для реализации кооперативного класса семафора, см. в разделе Как: Использовать класс Context для реализации кооперативного семафора.

Превышение лимита подписки

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

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

Примечание.

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

Чтобы включить превышение подписки в текущем контексте, вызовите метод concurrency::Context::Oversubscribe, установив параметр _BeginOversubscriptiontrue. При включении переподписки (oversubscription) в потоке, созданном Средой выполнения Concurrency, среда создает один дополнительный поток. После завершения всех задач, требующих избыточной подписки, вызовите Context::Oversubscribe, установив параметр _BeginOversubscription в false.

Вы можете несколько раз включить сверхподписку из текущего контекста, но вы должны отключить её столько же раз, сколько включили. Сверхподписка также может быть вложенной; то есть задача, созданная другой задачей, которая использует сверхподписку, также может перегружать свой контекст. Однако, если и вложенная задача, и её родитель принадлежат одному и тому же контексту, только самый внешний вызов Context::Oversubscribe приводит к созданию дополнительного потока.

Примечание.

Среда выполнения выбрасывает конкурентность::invalid_oversubscribe_operation, если оверсубскрипция отключена перед тем, как быть включенной.

Пример

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

См. также

Планировщик заданий
Практическое руководство. Использование групп планирования для определения порядка выполнения
Как использовать класс Context для реализации кооперативного семафора
Практическое руководство. Использование лимита подписки для устранения задержек