выход между разными процессами - PullRequest
5 голосов
/ 23 сентября 2011

У меня есть два кода C ++, один из которых называется a , а другой - b .Я работаю в 64-битном Linux, используя библиотеку потоков Boost.

Код a создает 5 потоков, которые остаются в бесконечном цикле, выполняя некоторую операцию.Код b создает 5 потоков, которые остаются в бесконечном цикле, вызывая yield ().

Я на машине с четырьмя ядрами ... Когда вызывается a один только код, он получает почти 400% загрузки процессора.Когда вызывается только код b , он получает почти 400% загрузки ЦП.Я уже ожидал этого.

Но при запуске обоих вместе я ожидал, что код b почти не использует ЦП, а a использует 400%.Но на самом деле оба используют равный срез процессора, почти 200%.

Мой вопрос: не работает yield () между разными процессами?Есть ли способ заставить его работать так, как я ожидал?

Ответы [ 2 ]

3 голосов
/ 23 сентября 2011

Итак, у вас есть 4 ядра, на которых запущены 4 потока, принадлежащих A. В очереди 6 потоков - 1 A и 5 B. Один из запущенных потоков A исчерпывает свой временной интервал и возвращается в очередь.Планировщик выбирает следующий выполняемый поток из очереди.Какова вероятность того, что этот протектор принадлежит B?5/6.Хорошо, этот поток запущен, он вызывает sched_yield () и возвращается в очередь.Какова вероятность того, что следующий поток снова будет потоком B?5/6 снова!

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

sched_yield предназначен для одного конкретного случая - когда один поток запускает другой поток (например, разблокирует мьютекс).Если вы хотите заставить B ждать, пока A работает над чем-то важным - используйте какой-нибудь механизм синхронизации, который может перевести B в спящий режим, пока A не разбудит его

2 голосов
/ 05 октября 2011

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

Когда поток использует весь свой временной интервал, ядро ​​понижает его приоритет, а когда поток не использует весь его временной интервал (выполняя IO, вызывая wait / yield и т. Д.), Ядро увеличивает свой приоритет.

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

...