Dealing with multi-player threads...

Started by
14 comments, last by hplus0603 18 years, 2 months ago
When I first started designing the classes and such for a MUD I was under the impression it would be easiest to have threads for each player, and each thread await input from the player, etc. Reading around these boards however, some people were mentioning that it isn't a good idea to do that. My question is, what are some methods (not methods in programming, just ways of doing it, haha) of dealing with user input? I've come up with a few ideas but it seems like they leave room for abuse if someone used a hacked client.
Advertisement
Have you taken a peek at how some other MUDs such as (CircleMud) have coded networking? The client to connect to these would usually be a simple Telnet terminal, so hacking it with that would be pretty tough.

I had thought they used threading (or forking) but it turns out they just use select() to determine who has sent data.

Anyway, if you have threading and the connection is blocked waiting for data, then it wouldn't be able to send out new information to the player, so that is one of the reasons I probably wouldn't choose that method of implementation.
I have it worked out so I can send data to the user whenever, and accept data from the user whenever, but are there any negative effects from each user having their own thread?
Quote:Original post by Kraiger
I have it worked out so I can send data to the user whenever, and accept data from the user whenever, but are there any negative effects from each user having their own thread?


There aren't any EXTRA negative effects. You'll still have to worry about the standard negative effects of threading, like tough debugging, simultaneous access issues, and confusing race conditions, on top of whatever overhead you might have for thread switching.
--Riley
There isn't really much advantage to be had by having one thread per client. Programming certain logic might be easier, because rather than having a state machine per client, you just use the program counter. Consider:

// pseudo-code// socket has been acceptedwhile (username is not acceptable) {  prompt for username;  check username for validity;}while (password is incorrect) {  prompt for password;  check password for validity;}logon user;while (player is still connected) {  process command;}close socket;// end of thread


However, this is likely to be outweighed by the more complex programming for the rest of the system, i.e. ensuring synchronised access to shared stuff, making sure threads are started / stopped cleanly.

Mark
That code structure can be written for each client using fibers (a k a "cooperative threads" or "coroutines"). Fibers are better than regular threads in that they don't require explicit locking for many cases (as they all execute within a single pre-emptive thread context).

You still have the cost of a fiber stack per fiber (just like the cost of a thread stack per thread), though, which may make them more expensive than you'd like for a system with many clients.
enum Bool { True, False, FileNotFound };
Hello, kind of new here. But thought I might put in my own 2 cents real quick.

As far as stack size goes, can't you set this so as not to take up too much space in memory? Not more than you need at least.

I've been writing some netowrk code for a small, "Battlefield"-type, game engine, and ( don't laugh ) went the multi-threaded route.

I went with hooking __event() functions from each thread to an event handler to funnel them into one area. From what I've read, it's thread safe, but books can be deceiving sometimes.

The way it is going right now, it looks like this will be a global message handler to modify game data. The main thread would also send messages here to handle game data modifications.

The only good thing I see about this so far, is that I can add in networking, physics, AI, input, etc modularly. The only worry now is about accessing data in a safe fashion. I may have to run the main function as a modData/getData function.

Anyhow, I'm just a home-brew hacker, so don't take anything I said with a grain of salt.
Jason BrooksGame Enthusiast[email=jbrooks113@comcast.net]jbrooks113@comcast.net[/email]
having developed an industrial strength vpn I can tell you that a good solution is to have a group of threads, and assign pieces of work to a thread (ie dispatcher),..when the piece of work is complete return the thread to the free thread pool.

a common thing i see these forums is people wanting to have one thread for receiving data on each connection. This is a big no no. When some data is indicated to be received, task it into a queue and have a free thread take care of the work.

multithreaded coding is difficult to develop and even more difficult to maintain, deadlocks are common mistakes, but with multicore cpus out there and growing you will all have to rethink how we develop software.

all the best.
Cubex
@Cubex: Interesting!

The typical problem with a distributed simulation (i e, most physically based games) is that everybody wants to mutate the same state database (i e, the game world), so you end up serializing everybody on "the world lock" anyway. Thus, trying to offload networking to more than one other thread just won't give you anything -- and trying to do event dispatching from multiple threads just won't be a win.

Designing compelling, server-authentic, physically based game mechanics that don't require a central datastore (at least per "zone" or "area") and also doesn't run the risk of deadlocks is something that I believe hasn't yet been done. I'd love to see the description of such mechanics if someone has it, though!

In what way is your VPN solution similar to a distributed simulation like this? Do you have some central datastore that all the connections need to access for each packet?
enum Bool { True, False, FileNotFound };
@hplus0603:

i think you are skillful in mmog server program, and would you tell me how many players a single-threaded server can process without obviouse delay(generic sever computer and do not take into account the bandwidth).

This topic is closed to new replies.

Advertisement