Wednesday, July 8, 2009

Concurrency on a single thread

When I wrote my article about concurrency, I did a bit of searching to find out how to use multi-threading in F#. One of the hits was a blog entry on HubFS by gneverov titled "Hell Is Other Languages : Concurrency on a single thread". At that time, I was a bit confused by the article. Why would one want single-threaded concurrency when we already had multi-threaded concurrency? Part of the answer lies in reactive programming.

Recently, I read an article by Shawn Hargreaves, "Pumping the Guide", where he describes some design issues with using the Guide on the Xbox. The Guide is the part of the Xbox GUI which is used for performing common operations, such as entering text, selecting a device where game data is saved, seeing which of your friends are online and what they are doing... The problem is to have the game still running in the background while the Guide is opened.

The solution chosen by the XNA team was to make calls to the Guide non-blocking. This however makes it harder for game developers to use it, as it forces them to keep track of the application state explicitly, including both the state of the game and the state of the Guide.

Kevin Gadd's shows a elegant solution to this problem in C# using custom enumerators in an article aptly named "Asynchronous programming for xna games with Squared.Task".

Kevin's implementation in C# is as pretty as it can get, but it would probably look even better in F# using asynchronous computations. Although the async { ... } notations is exactly what we want, the Async functions do not seem to support the kind of single-threaded concurrency that Kevin's Square.Task does.

The code by gneverov however should be easy to modify to execute one single step in one of the active tasks, if it does not already support that.

3 comments:

Steve Gilham said...

Single-threaded concurrency is pretty much what the Windows Workflow libraries are about -- transparently scheduling activities onto a single OS thread. This post makes me wonder whether it might be possible to hide some of the rote coding involved writing WF programs inside a monad (or several).

Anonymous said...

Indeed; I think Tomas (of http://tomasp.net/) has done some work in this direction... while the 'async' monad in the box does multi-threading, you can author similar a single-threaded monad, and leverage the F# computation expression syntax to make it easy to 'interleave' on a single thread. And I've thought that F# may make a good programming model for WF, but haven't had time to experiment with that.

Unknown said...

Yeah, I've been trying to build something like 'Persistable Workflows' to allow persisting state. Since lambdas are serializable that shouldn't be to hard. But I have too little experience with writing monads to build it.