Ответ 1
Согласно
вы можете избивать их волей-неволей. Попробуй! Они используют ThreadPool. Я не пробовал это для игрового приложения с графическим интерфейсом в реальном времени, но я не удивлюсь, если это будет "достаточно хорошо".
Я только что открыл MailboxProcessor в F #, и его использование в качестве "конечного автомата"... но я не могу найти много о рекомендуемом их использовании.
Например... скажу, что я делаю простую игру со 100 врагами на экране, должен ли я использовать MailboxProcessor для изменения позиции и здоровья противника; давая мне 200 активных MailboxProcessor?
Есть ли какое-нибудь умное управление потоками под капотом? должен ли я попытаться ограничить количество активного MailboxProcessor, которое у меня есть, или я могу продолжать их избивать волей-неволей?
Спасибо заранее,
JD.
Согласно
вы можете избивать их волей-неволей. Попробуй! Они используют ThreadPool. Я не пробовал это для игрового приложения с графическим интерфейсом в реальном времени, но я не удивлюсь, если это будет "достаточно хорошо".
Почтовый ящик для моделирования противника может выглядеть так:
MailboxProcessor.Start(fun inbox ->
async {
while true do
let! message = inbox.Receive()
processMessage(message)
})
Он не потребляет поток, пока ожидает сообщения (строка let! message =
). Однако, как только сообщение поступит, он будет потреблять поток (в пуле потоков). Если у вас есть 100 почтовых процессоров, которые все получают сообщение одновременно, все они будут пытаться проснуться и потреблять поток. Поскольку обработка сообщений связана с процессором, 100-разрядные процессоры почтовых ящиков будут просыпаться и запускать потоки нереста (поток пула). Это не очень хорошая производительность.
Одной из проблемных почтовых процессоров превосходит ситуацию, когда много одновременных клиентов отправляют сообщения одному процессору (представьте себе несколько параллельных веб-сканеров, которые загружают страницы и выводят результаты в очередь). Случай с экранными врагами выглядит по-разному - многие объекты реагируют на один источник сообщений (движение игрока/время).
Еще один пример, когда тысячи MailboxProcessors - отличное решение - это связанный с I/O почтовый ящик:
MailboxProcessor.Start(fun inbox ->
async {
while true do
let! message = inbox.Receive()
match message with
| ->
do! AsyncWrite("something")
let! response = AsyncResponse()
...
})
Здесь после получения сообщения агент очень быстро дает поток, но все равно должен поддерживать состояние через асинхронные операции. На практике это будет очень хорошо: вы можете запускать тысячи и тысячи таких агентов: это отличный способ написать веб-сервер.
Скажем, я делаю простую игру со 100 врагами на экране, должен ли я использовать MailboxProcessor для изменения позиции и здоровья противника; давая мне 200 активных MailboxProcessor?
Я не вижу причин использовать MailboxProcessor
для этого. Серийный цикл, вероятно, будет намного проще и быстрее.
Есть ли какое-нибудь умное управление потоками под капотом?
Да, много. Но он предназначен для асинхронного параллельного программирования (особенно масштабируемого ввода-вывода), и ваша программа на самом деле не делает этого.
Должен ли я попытаться ограничить количество активного MailboxProcessor, которое у меня есть, или я могу продолжать их избивать волей-неволей?
Вы можете ударить их волей-неволей, но они далеки от оптимизации, а производительность намного хуже, чем серийный код.