Thread-network question
I have the following: Some clients need to communicate with a server. However, they can not (for some reasons) connect to the server directly, so everything the clients want to send has to go through another server, lets call it server2. The second server are to recieve data from some clients, process it, and pass it on the the first server. I use a separate thread for each client. What is to prefer: That each client-thread processes the own data and passes it to the first server(and it needs to use some global locked objects to perform this) That each client-thread just puts the data into some kind of global (thread-safe) queue and then I have another thread that goes through the queue and do the processing/forwarding, i.e. I only use the client-threads to recieve the data and let another thread process it.
Your primary server (the one your clients connect to) is a client of server2.
I'd make it have a single thread that behaves as that client, and harvests a single queue that is populated by the user-clients.
So, server1 has a thread per client, plus another thread for communicating with server2.
Server2 has its network thread, and whatever actual processing thread you need.
Clients connect to server1. Their communications are recieved by a thread just for that client. You could choose to (I'd recommend) do *some* pre-processing here (before locking the queue for sends to server2). This way you can drop anything obviously invalid before going to the hassle of passing it on to server2.
That said, I really don't see the point in having a separate thread for each individual client - its not usually required. I suggest you look into batching the clients (look at socket pools / select methodology) to save yourself the overhead and headache of trying to track too many threads, especially when each of them could lock a common data store. It's MUCH easier to track deadlocks if there's only a couple of places it can happen.
I'd make it have a single thread that behaves as that client, and harvests a single queue that is populated by the user-clients.
So, server1 has a thread per client, plus another thread for communicating with server2.
Server2 has its network thread, and whatever actual processing thread you need.
Clients connect to server1. Their communications are recieved by a thread just for that client. You could choose to (I'd recommend) do *some* pre-processing here (before locking the queue for sends to server2). This way you can drop anything obviously invalid before going to the hassle of passing it on to server2.
That said, I really don't see the point in having a separate thread for each individual client - its not usually required. I suggest you look into batching the clients (look at socket pools / select methodology) to save yourself the overhead and headache of trying to track too many threads, especially when each of them could lock a common data store. It's MUCH easier to track deadlocks if there's only a couple of places it can happen.
Winterdyne Solutions Ltd is recruiting - this thread for details!
What are the alternatives to using a thread per client? I mean, when I listen for an incomming message, the read-method is blocking. But I know there are alternatives to this, but I dont know what the alternatives are :-)
And I'm know really worried about deadlocks, since it's hard to believe they will occur in this case. (it's only the processing-thread that is waiting for the client-threads to fill the queue, and it will be awakened by those threads). It's just a matter of efficiency.
By the way, it's to be implemented in C#.
And I'm know really worried about deadlocks, since it's hard to believe they will occur in this case. (it's only the processing-thread that is waiting for the client-threads to fill the queue, and it will be awakened by those threads). It's just a matter of efficiency.
By the way, it's to be implemented in C#.
Ok, I can't help with the C# side, just the general method:
The best alternative is to use a nonblocking socket and select method. The select call provides/fills a list of sockets with incoming data, which can then be read. Select can be called either to wait for a certain amount of time or (preferably) to return immediately with what's there, so you're effectively polling your sockets.
Because you can't guarantee the run order of your threads, you should always be aware that ANY shared container is a potential deadlock. Mutexes are most definitely your friend.
The best alternative is to use a nonblocking socket and select method. The select call provides/fills a list of sockets with incoming data, which can then be read. Select can be called either to wait for a certain amount of time or (preferably) to return immediately with what's there, so you're effectively polling your sockets.
Because you can't guarantee the run order of your threads, you should always be aware that ANY shared container is a potential deadlock. Mutexes are most definitely your friend.
Winterdyne Solutions Ltd is recruiting - this thread for details!
The alternative is you use Async Networking. This is how I do all of my networking. You have a callback to handle the receiving of information, it prevents blocking.
theTroll
theTroll
Well, this is what I want to use it for:
The server should recieve som data from the clients. It should parse it and then put it in a database. Then, it should use the data to communicate with the second server (send some data, recieve an aknowledgement and send something more, something like that). It can only "serve" one client at a time. What is the best design? (when it comes to threads/sockets)
The server should recieve som data from the clients. It should parse it and then put it in a database. Then, it should use the data to communicate with the second server (send some data, recieve an aknowledgement and send something more, something like that). It can only "serve" one client at a time. What is the best design? (when it comes to threads/sockets)
The best design is the one that you believe you can implement, debug and deploy with the least effort, while still adhering to the requirements that you have (regarding uptime, scalability, functionality, maintainance, etc).
Given that we don't know what you know and don't know, and very little about your requirements, we can't really recommend the "best" design for you.
Given that we don't know what you know and don't know, and very little about your requirements, we can't really recommend the "best" design for you.
enum Bool { True, False, FileNotFound };
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement