WIN32: передача выполнения другому (заданному) потоку - PullRequest
7 голосов
/ 07 января 2010

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

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

Ответы [ 8 ]

7 голосов
/ 07 января 2010

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

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

Однако есть несколько способов повлиять на переключение контекста:

  • увеличивая приоритет определенного потока, вы можете заставить планировщик планировать его чаще в ущерб другим потокам (очевидно, применяется и обратное - вы можете понизить приоритет другие темы)

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

Примечание. Редко возникает причина, по которой вам следует вмешиваться в приоритеты задач, поэтому ИСПОЛЬЗУЙТЕ ВНИМАНИЕ

2 голосов
/ 12 января 2010

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

2 голосов
/ 08 января 2010

Посмотрите на потоки UMS (планирование в пользовательском режиме) в Windows 7

http://msdn.microsoft.com/en-us/library/dd627187(VS.85).aspx

2 голосов
/ 07 января 2010

Вы можете использовать «волокна» вместо «нитей»: например, есть Win32 API с именем SwitchToFiber , который позволяет указать волокно для планирования.

1 голос
/ 07 января 2010

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

1 голос
/ 07 января 2010

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

1 голос
/ 07 января 2010

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

0 голосов
/ 13 января 2010

Могу ли я спросить , почему вы хотите использовать SwitchToThread?

Если, например, это какая-то форма, потому что поток x вычисляет какое-то значение, которого вы хотите ожидать в потоке Y, тогда я бы действительно посоветовал взглянуть на библиотеку Parallel Pattern Library или Asynchronous Agents Library в Visual Studio 2010, которая позволяет Вы можете сделать это либо с помощью блоков сообщений (получать с асинхронным значением), либо просто с помощью задач: дождитесь завершения набора задач и встроите их выполнение во время ожидания ...

//i.e. on an arbitrary thread
task_group* tasks;
tasks->run(... / some functor/)

вызов задач-> wait () будет ожидать и включать любые выполняющиеся задачи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...