Sign in to follow this  
Nodlehs

Question about threading and sockets.

Recommended Posts

I have been an application programmer for a while now, and am now in my spare time messing around with some game ideas. Having been a fan of many a MUD I thought I would tackle that as a stepping stone to something more graphically intense. I am writing this from scratch, and already have plenty of code from other projects I can resuse for this project. My main concern is the threading and socket aspects of the project. I haven't had any experience in socket coding before but have managed to put together my own little library for it which I think functions quite well. I have read the forum faq, I was most interested in the thread per connection idea, and I also had the misgivings it points out that I would end up blocking a lot, lots of useless context switches as well. I still want to use threads, and was wondering what common practice is? I was thinking of using 1 thread to process a queue of commands from users, a second to listen for incoming connections, and a third to read/send data from a fd_set. Each player would have in its struct a list of data to send back, commands recieved from the players socket would be inserted in the command queue for thread 1. I know I would need to lock the command queue on each command recieved from a player, as well as lock the player struct on each command that affected a player. Is this a good design? or is there really no reason to break it up into threads? Any ideas/comments on the design would be much appreciated.

Share this post


Link to post
Share on other sites
separate working layer into follow


1. network event dispatching layer [ receiving, accept, error control ]
this layer maybe IOCP or select threading and accept threading

2. network send layer
if unix style platform, multiple threading consists of send scheduling

3. problem domain [ main logic ] worker layer
synchronizing message queueing
multiple worker threading [ process login/logout/chatting/moving/attack ]
this layer depended on server distribution model

example for my project

1. network event dispatching layer
1 thread for Server IPC
n thread for Client per Accepting that consists of connection load-balancing

2. network send layer
because of used IOCP, this layer not presented. in other words, O/S worked that.

3. problem domain worker layer
connection matched with server side controll class [example CGameWorld ]
n multiple threading each other encapsulated into CWorker class[object]
Each controll object divided into an Spartial Worker Class
CWorker class aggregates[ using map datastructure ] controll objects.
Synchronization with specified CWorker objects.


and your idead is useful~. but your logic layer has single threading. so you wanaa improve performance, using multiple threading as my instance. But this issues and activity is very harmful because of synchronization[ thread control, deadlock, livelock( cross-deadlock ) ].

GoodLuck, and u wanna some example code or some project code or library, send to my email veruna2k@hotmail.com, and then i reply them to you.

Share this post


Link to post
Share on other sites
Quote:
1 thread to process a queue of commands from users, a second to listen for incoming connections, and a third to read/send data from a fd_set.


When you read a command from an fd_set, and want to put that command into a queue, you may end up serializing on the command queue between the read thread and the processing thread. This can be designed around, and/or you can optimistically assume that the window of contention is small and won't hit.

When you listen for an incoming connection, and need to add a new user to the set of users that can have commands, and to the set of sockets in the fd_set that you're going to listen to, the accepting thread will serialize both with the processing thread, and with the networking thread. Again, you can assume that the window of contention is small, so it won't necessarily hurt you.

However, unless your game logic is dead simple, you're going to spend the lion's share of your CPU time inside the thread that processes user commands. The additional CPU time spent in the network send, receive, and accepting threads will likely be a handful of percent of CPU. Meanwhile, you are spending CPU/memory bandwidth on synchronizing between the threads. Even with a dual-CPU system, it's un-clear whether you'll get much out of your threading. With the described architecture, I'd just put everything in a single thread, to squeeze a few more percent of performance out of your available CPU/memory bus.

If the reason to use threading is simply that you find it better to think that way, then go right ahead. What you're describing will work -- I just don't see the actual gains of using threads, and I do see a little bit of cost. If the cost buys you something like "I can think clearly about it, and thus will finish the game," then it's certainly worth it.

Share this post


Link to post
Share on other sites
[quote]Original post by hplus0603
Quote:
... a little bit of cost. If the cost buys you something like "I can think clearly about it, and thus will finish the game," then it's certainly worth it.

Definitely that is the main thing. There will be plenty of other issues to deal with as you work on the project.
I was looking for info about this and found the following page which you may find interesting
http://www.microsoft.com/mspress/books/sampchap/5726a.asp
It says that a really large fd_set causes cpu hogging, but they are talking about many thousands of clients. So I don't think you will see any cpu problems from this, it's more likely to be waiting for locks a lot that will drop performance. Like already said even dual cpus will not be used to their full potential. By the way
Quote:
I know I would need to lock the command queue on each command recieved from a player, as well as lock the player struct on each command that affected a player
I'm not sure why you need to lock the player struct on each command that affected a player, there is only one thread that accesses player info, no? Or does your third thread (read/send data) access player info?

Share this post


Link to post
Share on other sites
Thanks for the replies so far.

Quote:
I'm not sure why you need to lock the player struct on each command that affected a player, there is only one thread that accesses player info, no? Or does your third thread (read/send data) access player info?


I wasn't entirely sure how I wanted to design my player struct. I was originally thinking about having a list in each player struct that contains outgoing data, but am thinking it might be better to make an output queue, a struct at each node with the players socket and the message. I may just make it a single threaded server anyway, as it seems I have little to gain separating my networking from my main game loop(if I am using a select on a fd_set). Like hplus0603 said, I will be spending most of my time in my main loop processing each command. The idea of threads was just to keep things separate, mainly because its what I am used to, not to keep it clear in my head, just habits. In my normal work we work remotely or in teams, so I am just used to interfacing with other people modules and not having access to the whole projects code.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this