I'm coding in C++. I have a server that will have clients connect to it, and each client gets spun off into its own thread for communication. This server is hosting a game, so there is information that must be shared between all client threads, as well as any other threads I choose to spawn off. This data is like level data, players online, etc, so all threads might possible have to access any of the data at any time. When I was doing this in C#, I just had a static static with all static fields. Is there a superior way to do this? I really don't want to have to deal with passing a reference to a specific object everywhere, but I figure my current implementation goes against OOP etc. Would this be a good case for using a singleton design pattern? Any other ideas are welcomed!
3 main ways of doing this:
Use a global static object, its gets constructed at startup and can be a good pattern as it is very simple. Simple can often = good.
Use a singleton. You now have the object created later, and its still a single object. you fetch this object as needed. This is a "step-up" as you have more control about initialisation of the object compared to the global.
Use an 'Inversion of Control' object. This is basically passing the object into each class in the constructor, so each object has its private member pointer to the object. This is another step-up as it allows much easier access to the 'global', and also allows you to switch the injected object on a class by class basis.
Ultimately it depends, the IoC pattern is very fashionable at the moment, but I tend to prefer the global TBH. It depends as well what data you're putting into it, and if its a read-only or a read-write object.
I really don't want to have to deal with passing a reference to a specific object everywhere
Why not? Is passing a single reference so much effort? You'll kick yourself tomorrow when you use a global variable just because you were too lazy today to implement it properly.
Just send the reference and get it done.
each client gets spun off into its own thread for communication
Not a fan of Boost.Asio?
there is information that must be shared between all client threads
Sounds like you just want a giant global table that any client instance (whether a thread or an Asio implementation) can read and write.
There are a couple of other options not mentioned yet:-
Shared memory. Use the POSIX Interprocess Communication and Shared Memory APIs to allocate and control a piece of shared memory. The advantage is that you can now share the data between processes which will scale well within a single machine.
Use a mini server process, which can be accessed via the technology of your choice (RPC, CORBA, plain TCP/IP sockets). This will scale well over multiple machines, but, you need to write a fairly complex API to manage updates etc.
Use a database. Sounds like overkill but this is exactly what database management systems were written for. This scales up to almost Facebook/Amazon size provided you are careful with your SQL, and, you don't need to write much code to implement this.