Регулирование потока в C#
Я создал игру в VS2010, используя VB .NET 4 в C#. Игра создает поток для каждого игрока и запускает код LUA, созданный игроками.
Каждый код LUA блокирует поток и должен завершаться только после завершения потока (сценарий LUA должен содержать бесконечный цикл)
Я хочу ограничить использование ЦП, так как компьютер в настоящее время перегревается после работы с 100% ЦП в течение нескольких часов.
Как я могу дросселировать нити, не имея контроля внутри них? Я надеялся иметь диспетчер потоков для принудительного приостановления / возобновления, но они становятся устаревшими, и я не хочу генерировать исключения, потому что это прервет мой код LUA, который выполняется.
Есть идеи?
Спасибо!
3 ответа
Для этих потоков можно установить низкий приоритет приоритета - это поможет вашей системе оставаться отзывчивой... но вы все равно будете использовать 100% ЦП и перегреваться, поэтому я не буду вдаваться в подробности того, как это сделать.
Как уже упоминалось в других постерах, вам нужно заставить свои темы вставлять маленькие спящие. Если вы вообще не можете их контролировать, вы больше ничего не можете сделать.
Я бы посоветовал вам изменить свой игровой API.
Вместо того, чтобы ваш код вызывал код Lua один раз, а затем код Lua с бесконечным циклом, я бы посоветовал вам сделать так, чтобы код Lua имел функцию "Выполнить один кадр". Затем вы перемещаете бесконечный цикл в свой собственный код и повторно вызываете функцию "Выполнить один кадр".
Таким образом, вы можете вставлять спящие, добавлять журналы и делать другие полезные действия.
Типичный способ удостовериться, что поток в бесконечном цикле не потребляет слишком много ресурсов процессора, - это заставить его немного спать в каждой итерации (обычно 5 мсек). Это даст системное время, чтобы другие ресурсы могли использовать процессор. Также не стоит отдавать темы наивысший приоритет.
Классический способ получить контроль над планированием потоков выполнения - использовать Fibers.
Тем не менее, Fibers - это встроенная функция WIN32 API.... самое близкое, что вы можете получить в C#, это использовать итераторы... где вы выполняете часть работы между каждым выходом.... но вы решаете, когда хотите следующий немного работы, которую нужно выполнить, вызвав итератор.
См. 2-ую ссылку... может быть способом использовать неуправляемый собственный API Fiber для упаковки некоторых сопрограмм.NET, или если код LUA, который вы запускаете в этом потоке, является собственным, и у вас нет доступа к исходному коду... Тогда вы можете использовать ConvertThreadToFibre, чтобы получить контроль над ним (и решить, когда он будет запланирован, используя некоторое взаимодействие с вызовами Fiber API).
http://paoloseverini.wordpress.com/2012/02/02/implementing-iterator-blocks-in-c-part-2-win32-fibers/
http://www.altdevblogaday.com/2011/05/25/implementing-fibers-in-c/
http://www.altdevblogaday.com/2011/02/01/slim-and-light-multitasking-with-fibers/
Волокна в C#: они быстрее чем итераторы, и люди использовали их?
Или у вас может быть поток планирования, который использует События, чтобы сигнализировать потокам проигрывателя, когда они могут продолжить и выполнить некоторую работу (если какой-то ваш код является собственным /C++, а другой - C#, то каждый может ссылаться на одни и те же дескрипторы событий.... Просто используйте WIN32API или.NET API в каждом бите кода).