Small online 2d RPG game, single vs. multithread server?

Hey.
I recently went back to using one threaded server - because the thread handling was killing me. Concurrency errors and such…
My initial plan was to use 3 threads on the server :

  1. Logic, calculations etc
  2. Database write/read
  3. Network in/out

However, like I said now I am back to one… :confused:

My question is if this is even going to be viable in the long run?
I am guessing it has to do with the number of clients connecting to it as well?

Can someone give me some pointers on this? Do I -need- multi threads or can single do fine for a limited (how many?) number of clients?

For a simple 2d roleplaying game, I’d assume that single threaded ought to be fine. I used to work in telecommunications and I wrote single threaded servers that handled thousands of messages a second on standard intel boxes of the day (over a decade ago!), and that was with some pretty intensive processing as well.

I think that worrying about multiple threads is way overcomplicating things. Get it working first in a simple fashion and if you think you need to get more performance out of the server later, then consider a refactor for multithreading at that stage.

Handling your game in a single thread is fine, as long as you don’t perform any operations that block.

To write a client-server networked game, you need at least 1 + 1 + 1 threads on the server:
A listener thread over the server port, that accepts connections (blocks until received request) and spawns …
… An execution thread over the connected client socket that handles client communications. Since that will have to block on listening, you will probably need …
… Another execution thread that does all the ‘server’ side stuff for this client.

Draft calculation: 1 + (2 x NumberOfClients) threads.

Single Threaded Network Server:
Can happen, but will have to serve only one client at any time, and close the socket/end connection to serve another.
Only in textbook examples I’ve seen such (e.g. echo, hello, time-server, etc).

adon you can do it but it is just less organized

1 thread:
a. server listens on port - blocks until receives connection
b. blocks on listening on connection
c. receives info, processes, sends back response, closes socket (or save it for later reuse)
d. back to (a) or (b)

Is that what you mean h3ckboy?

You might want to read about Java NIO: non-blocking I/O.

you should use a network thread to handle network request and fill a stack with them, then for each server “logical loop” you will read this stack and pop any complete packets ready to be proceded (depending on your application architecture do the same for sending)

about multithreaded application :
you should multithread atomic part of your full server process, dont use a thread for logic another for task2 and another for task 3 is better to do the following :

let say you have 3 task to do then

perform task 1 multithreaded on n threads (n depending on number of processor / core should be equals or greater)

wait for task 1 to be fully finished

perform task 2 on n threads

wait for task to to finish

perform task 3 on n thread

wait for task 3 to finish

the big advantage of doing that way is that :
1 - you will perform similar task on n different core so if you split equally they should end approximatly at the same time and will result in an optimal cpu usage
2 - it let you think like single threaded application and do not suffer of concurency access

If you don’t need it. Using a single thread is recommended.

I was doing SMP type stuff before Java was born, so multi threaded is not new to me or the industry. Yet I generally write things single threaded when i can get away with it. Life is just so much simpler. Try running a debugger with multi threaded apps!!

When i do decide its worth it. Then i keep the interface between threads very simple. With classes from java.util.concurrent you can communicate between threads without even knowing what a lock or semaphore is. Its Brilliant. One thread is putting “data” into one end of a thread safe que and some other threads takes em out again. And the thread that takes em out blocks when there is nothing there. On top of that most things in java.util.concurrent have fairness options, that can make a big difference if you are getting starved threads.

Last but not least I use read/write locks in cases when i almost don’t update but read a data structure a lot. My fluids code in AoI uses this and the locking overhead all but undetectable.

finally i use assertions a lot so that when things start to go wrong, I get errors as soon as it happens. AspectJ can help with some debug stuff to with the right kind of cutpoints.

But really, “mutlicore ready” is overrated. I would prefer “works most of the time” .

To be clear, this is wrong. As Riven mentioned, look at NIO.

Non-blocking I/O is just blocking, with the threads I mentioned spawned in the background.
Not much easier to use or control concurrency, than the blocking home-brewed version I described.

I think DzzD’s approach is the most scalable thread-wise.

PLEASE read up on Java NIO ::slight_smile:

Just for the record. Since some people may never read a manual :wink: Java non blocking is the same as non blocking io in other langs. Its a feature provided by the OS and underlying hardware. Buffers can be filled etc without user space threads doing the work, indeed often no threads at all (DMA). The api generally means every method call will return immediately, even if there is nothing to read etc.

I have a single thread manage all my network connections. Thats 2 different server sockets and any number of connections that are opened from these server sockets. Simply you check to see if anything has happened since the last time you checked. Then you go through the list of things, like connection request or whatever, process that then move to the next thing. Which may be data is avalible on connection 2 or you can write to connection 9. It works very well and is much more effectent than the spawn a thread per connection that was done to fake non blocking io previously.

Keep in mind that a cpu can pump far more data into a network card than the card can send/receive. So filling/emptying bufferers then waiting till they are empty/full again really makes a lot of sense. (yes i know the buffers should never get “full”)

Doing a full game with network support in a single thread is quite doable.

[quote=“delt0r,post:13,topic:34394”]
Well… if you have enough RAM to spare to have all those (Linux NPTL) threads around, read this:

even when I was dealing with socket in C/C++ I always found simpler to use another thread, this ensure every packet is read ASAP and I found it, IMHO, a lot more clear

Well thanks for the feedback guys.
Since there seem to be no real “No it’s impossible” answer, except one guy who is against it…
I will keep going with my current single threaded version.
It uses NIO sockets (that’s the name?), anyway the class handling my sockets can read non-blocking or blocking depending on what I want to use.

I really know far too little about multi-threads to feel secure about it, whenever I try it seems I get bugs… even tho I REALLY try to avoid it hehe.

How can you use single threaded server architecture to support multiple user simultaneously?

Answer:

there are two ways of working with socket blocking & unblocking, when they are not blocking you can ust check if something is available to read and if not check the second and third and etc…

The problem is that your writes can be blocking. You can’t poll them like InputStreams.