Поведение sched_yield
У меня мало вопросов о функции sched_yield
, потому что я вижу, что он не работает в моем коде. Много раз я вижу, что тот же поток запускается снова и снова, даже при наличии других потоков, когда я пытаюсь уступить его, вызывая sched_yield
.
Также, если у меня есть multicores, будет sched_yield
выход для потоков, запущенных на всех ядрах, или только одно ядро. Например, у меня есть потоки 1, 2 и 3, работающие на ядре 1 и Threads 4, 5 и 6 на ядре 2, и если sched_yield
вызывается из Thread 2, он будет заменен только Thread 1 и 3 или 1, 3, 4, 5 и 6 возможны? Я спрашиваю об этом, потому что в .Net Thread.Yield
выводится только потоки, запущенные на одном и том же ядре/процессоре.
Ответы
Ответ 1
http://www.kernel.org/doc/man-pages/online/pages/man2/sched_yield.2.html
sched_yield() заставляет вызывающий поток отказываться от CPU. Нить переместился в конец очереди для своего статического приоритета, и новый поток попадает в работать.
Если вызывающий поток является единственным потоком в списке с наивысшим приоритетом времени, он будет продолжать работать после вызова функции sched_yield().
Функция sched_yield не является .Net-вызовом, а модель потока/процесса отличается. Планировщик Windows/.NET отличается от планировщика Linux. Linux даже имеет несколько возможных планировщиков.
Итак, ваши ожидания относительно sched_yield ошибочны.
Если вы хотите контролировать, как выполняются потоки, вы можете привязать каждый поток к CPU. Затем потоки будут выполняться только на привязанных CPU. Если у вас будет несколько потоков, привязанных к одному и тому же процессору, использование sched_yield MAY переключится на другой поток, привязанный к текущему CPU и готовый к запуску.
Также может быть плохой идеей использовать несколько потоков для каждого процессора, если каждый поток хочет сделать много работы с интенсивным процессором.
Если вы хотите получить полный контроль, как выполняются потоки, вы можете использовать потоки RealTime. http://www.linuxjournal.com/magazine/real-time-linux-kernel-scheduler - политики SCHED_FIFO и SCHED_RR RT.
Ответ 2
Почему вы хотите отказаться от процессора? Ну...
Я исправляю ошибку в клиентском коде. В принципе, у них есть общая структура, которая содержит информацию:
- сколько монет в escrow - вернуть их
- сколько счетов в escrow - вернуть их
Вышеизложенное происходит в процессе A. Остальная часть кода находится в процессе B. Процесс B отправляет сообщения процессу A для вычисления и возврата денег в escrow (это торговый автомат). Не вдаваясь в историю, почему код написан таким образом, исходная кодовая последовательность:
(процесс B) отправить сообщение RETURN_ESCROWED_BILLS для обработки A отправить сообщение RETURN_ESCROWED COINS to Process A Нулевая общая структура
Выполняется как:
(процесс B): отправлять сообщения; обнулить структуру;
(позже.. Процесс A): получать сообщения; все поля в общей структуре равны 0; ничего не делать;
Упс... деньги все еще находятся в депонировании, но процесс Код потерял эти знания. Что действительно необходимо (кроме массивной реструктуризации кода):
(процесс B): отправлять сообщения; получить процессор;
(Процесс A): определять денежные средства и возвращать; получить процессор; (может просто перейти к концу тайм-лиза, не требуется специальный метод)
(процесс B): обнулить общую структуру;
В любое время, когда у вас есть сообщения IPC, и процессы, которые отправляют/получают сообщения, тесно связаны. наилучшим способом является двухстороннее рукопожатие. Тем не менее, есть случаи (обычно в результате плохой или несуществующей конструкции), где вы должны тесно связать процессы, которые действительно должны быть слабо связаны. Обычно выход процессора - это взлом, потому что у вас нет выбора. Добавление многоядерных процессоров является источником боли, особенно при переносе от одного ядра к многоядерному.