Un MailboxProcessor per nemico simulazione potrebbe essere simile a questo:
MailboxProcessor.Start(fun inbox ->
async {
while true do
let! message = inbox.Receive()
processMessage(message)
})
non consuma un filo mentre si attende un messaggio per arrivare (let! message =
line). Tuttavia, una volta arrivato il messaggio, verrà utilizzato un thread (in un pool di thread). Se disponi di 100 processori di caselle postali che ricevono tutti un messaggio simultaneamente, tenteranno tutti di svegliarsi e consumare un thread. Poiché qui l'elaborazione dei messaggi è vincolata dalla CPU, 100s dei processori della casella di posta si sveglieranno e avvieranno i thread di spawning (pool di thread). Questa non è una grande prestazione.
Una situazione in cui i processori delle cassette postali eccellono è la situazione in cui sono presenti numerosi client concorrenti che inviano tutti messaggi a un processore (immaginate diversi web crawler paralleli che scaricano tutte le pagine e affondano i risultati in una coda). Il caso dei nemici sullo schermo appare diverso: sono molte le entità che rispondono a una singola fonte di messaggi (movimento del giocatore/battiti del tempo).
Un altro esempio in cui migliaia di MailboxProcessors è una grande soluzione è di I/O MailboxProcessor bound:
MailboxProcessor.Start(fun inbox ->
async {
while true do
let! message = inbox.Receive()
match message with
| ->
do! AsyncWrite("something")
let! response = AsyncResponse()
...
})
Qui dopo aver ricevuto un messaggio l'agente produce molto rapidamente un filo, ma ancora ha bisogno di mantenere lo stato tra le operazioni asincrone. Questo si ridurrà molto bene nella pratica - è possibile eseguire migliaia e migliaia di tali agenti: questo è un ottimo modo per scrivere un server web.
fonte
2010-08-09 21:02:25
Come ho sottolineato nella mia risposta di seguito, in caso di molti molti nemici sullo schermo, se si fa un agente per enimy, una volta ricevuto un messaggio, probabilmente farà una quantità di lavoro non banale, quindi proverai eseguire una quantità enorme di lavoro che tenta di essere parallelo. Non c'è alcun motivo per farlo: ci sono solo così tanti thread che il tuo processore può davvero funzionare in parallelo. Così hai tanti processori quanti ne hai e dividi i nemici tra loro. –
Il ThreadPool lo farà per lo più, sì? Crea il lavoro più "parallelo" che desideri e lascia che il ThreadPool faccia il suo lavoro per pianificare il lavoro in modo significativo. – Brian
Si ottiene un sovraccarico del pool di thread per messaggio che non è del tutto eccezionale. Ho ampliato la mia risposta qui sotto per spiegare i trade-off. –