Принудительное переключение контекста в Windows - PullRequest
3 голосов
/ 01 мая 2011

Есть ли способ принудительного переключения контекста в C ++ для конкретного потока, если у меня есть дескриптор потока или идентификатор потока?

Ответы [ 6 ]

4 голосов
/ 01 мая 2011

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

Поддерживается явное переключение контекста, вам придется использовать волокна.Просмотрите SwitchToFiber ().Волокно - далеко не нить, это похоже на старую рутину.Расцвет волокон пришел и ушел, они больше не конкурируют с нитями.Они имеют очень дрянную локальность кэша процессора и не могут использовать преимущества нескольких ядер.

4 голосов
/ 01 мая 2011

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

yield в Win32 API - это функция SwitchToThread.Если нет другого доступного потока для выполнения, то будет возвращено значение ZERO , и текущий поток все равно продолжит работу.

2 голосов
/ 01 мая 2011

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

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

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

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

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

1 голос
/ 08 июля 2012

Вы можете создать два объекта синхронизации (например, два события ) и использовать API SignalObjectAndWait .

Если hObjectToWaitOn не сигнализирован, а ваш другой поток ожидает на hObjectToSignal, ОС может теоретически выполнить быстрое переключение контекста внутри этого API, до конца временного интервала.

И если вы хотите, чтобы текущий поток автоматически возобновлялся, просто сообщите небольшое значение (например, 50 или 100) в dwMilliseconds.

1 голос
/ 19 февраля 2012

Я бы ознакомился с книгой «Параллельное программирование для Windows». Кажется, планировщик делает несколько вещей, на которые стоит обратить внимание.

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

1 голос
/ 01 мая 2011

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

// Wait until other thread releases lock
SetThreadPriority(otherThread, THREAD_PRIORITY_HIGHER);
while (InterlockedRead(&lock) != 0)
  Sleep(0);
SetThreadPriority(otherThread, THREAD_PRIORITY_NORMAL);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...