Thursday, October 28, 2010

C# random number generator starts returning only zero

Yesterday my game AI started going haywire on me. At a random point, all of my creatures would start moving in a single direction.

Turns out the cause was Random.NextDouble starting to return only zero. And it turns out the cause of that was multiple threads accessing the same instance of the Random class.

As I would have expected had I thought about it, Random is not thread safe. If it gets accessed from one thread while it is in the middle of an operation for another, its internal state gets mucked up and it just spits back zeros from then on.

The solution is to use one instance of Random per thread (which is what I did) or to ensure synchronized access.

5 comments:

  1. Are you using [ThreadStatic] or just manually controlling cross-thread access to your Random instances?

    ReplyDelete
  2. I just had one instance for my render thread and one for my physics thread. I'll run into problems if a method is used by both threads, though, so using the ThreadStatic attribute is probably a better way to go.

    ReplyDelete
  3. Turns out that [ThreadStatic] isn't supported on the Xbox :-(

    ReplyDelete
  4. Yeah, it's a shame about the lack of support for it on Xbox 360.

    I wrote up an article about alternatives here:
    http://www.gavpugh.com/2010/11/29/xnac-thread-local-storage-on-xbox-360/

    Might help you if you want to keep the interface to your 'Random' instance generic.

    ReplyDelete
  5. Thanks, Gavin - I'll check it out.

    ReplyDelete