开发者

MailboxProcessor usage guidelines?

I've just discovered the MailboxProcessor in F# and it's usage as a "state machine" ... but I can't find much on the recommended usage of them.

For example... say I'm making a simple game with 100 on-screen enemies should I use a MailboxProcessor to change enemy position and health; giving me 200 active MailboxProcessor?

Is there any clever thread management going on under the hood? should I try and limit the amount of active MailboxProcessor I have or can I keep banging them out wi开发者_StackOverflow中文版lly-nilly?

Thanks in advance,

JD.


A MailboxProcessor for enemy simulation might look like this:

MailboxProcessor.Start(fun inbox ->
async {
  while true do
    let! message = inbox.Receive()
    processMessage(message)
})

It does not consume a thread while it waits for a message to arrive (let! message = line). However, once message arrives it will consume a thread (on a thread pool). If you have a 100 mailbox processors that all receive a message simultaneously, they will all attempt to wake up and consume a thread. Since here message processing is CPU bound, 100s of mailbox processors will all wake up and start spawning (thread pool) threads. This is not a great performance.

One situation mailbox processors excel in is the situation where there is a lot of concurrent clients all sending messages to one processor (imagine several parallel web crawlers all downloading pages and sinking results to a queue). On-screen enemies case appears different - it is many entities responding to a single source of messages (player movement/time ticks).

Another example where thousands of MailboxProcessors is a great solution is I/O bound MailboxProcessor:

MailboxProcessor.Start(fun inbox ->
async {
  while true do
    let! message = inbox.Receive()
    match message with
    |  ->
         do! AsyncWrite("something")
         let! response = AsyncResponse()
         ...
})

Here after receiving a message the agent very quickly yields a thread but still needs to maintain state across asynchronous operations. This will scale very very well in practice - you can run thousands and thousands of such agents: this is a great way to write a web server.


As per

http://blogs.msdn.com/b/dsyme/archive/2010/02/15/async-and-parallel-design-patterns-in-f-part-3-agents.aspx

you can bang them out willy-nilly. Try it! They use the ThreadPool. I have not tried this for a real-time GUI game app, but I would not be surprised if this is 'good enough'.


say I'm making a simple game with 100 on-screen enemies should I use a MailboxProcessor to change enemy position and health; giving me 200 active MailboxProcessor?

I don't see any reason to try to use MailboxProcessor for that. A serial loop is likely to be much simpler and faster.

Is there any clever thread management going on under the hood?

Yes, lots. But is it designed for asynchronous concurrent programming (particularly scalable IO) and your program isn't really doing that.

should I try and limit the amount of active MailboxProcessor I have or can I keep banging them out willy-nilly?

You can bang them out willy-nilly but they are far from optimized and performance is much worse than serial code.


Maybe this or this can help?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜