Регулирование потока в 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).

Или у вас может быть поток планирования, который использует События, чтобы сигнализировать потокам проигрывателя, когда они могут продолжить и выполнить некоторую работу (если какой-то ваш код является собственным /C++, а другой - C#, то каждый может ссылаться на одни и те же дескрипторы событий.... Просто используйте WIN32API или.NET API в каждом бите кода).

Другие вопросы по тегам