Jump to content
  • Advertisement
Sign in to follow this  
spree

Thread help

This topic is 4952 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey, I need to make a simple client server CHAT project in c++. When a client is connecting to a server, the server oppens a new thread and begins the communication with the client using this thread. When a client sending a string (chat msg) the server receives it and sends it to all the clients connected. Now my questions is this: if all the clients connected to the server in threads. how can i tell each thread to send a msg. I understand that the thread is a single function. Can i make the thread be a whole class? So i can have Thread.ListenFunc() constantly running and when the server needs to send a msgs to all the threads I'll call Thread.send(msg) from the main func. is it posibble?

Share this post


Link to post
Share on other sites
Advertisement
I'm thinking of that you should build a collection of all client connections over threads. After that you may call "SendAll" function for sending message to all clients.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
instead of creating a thread per client, it would be much more practical to just use asynchronous sockets over your main thread.

Share this post


Link to post
Share on other sites
To answer the original question, what is the specific problem?

If you have a good sockets implementation, then you can write on a socket from one thread while blocking to read from another. However, not all sockets implementations support this. If that doesn't work for you, I would suggest using select() in a single thread. In fact, I would suggest single-threaded no matter what :-)

Here are the two approaches, in beautiful pseudo-code:


// multi-threaded implementation
LockOfSomeSort gConnectionsLock;
std::list< Connection > gConnections;
// in each thread
while( myConnected ) {
read( mySocket, intoBuffer );
// I read a message -- better send it to everybody.
// Because I'm threaded, I have to hold a lock, that
// everyone will hold when accessing gConnections, so
// there's no race between the list being modified.
gConnectionsLock.Lock();
std::for_each( gConnections.begin(), gConnections.end(), write( intoBuffer ) );
gonnectionsLock.Unlock();
}



// single-threaded implementation
std::list< Connection > gConnections;
while( true ) {
select( &ready );
// select() will have returned a bunch of read-to-read
// sockets. I'll read all the messages from those sockets
// into a list of messags to process.
std::list< Message > messages;
std::for_each( gConnections.begin(), gConnections.end(), readInto( messages ) );
// My "processing" of messages just means forwarding them
// to everybody.
std::for_each( messages.begin(), messages.end(), sendToAll( gConnections ) );
}

Share this post


Link to post
Share on other sites
Thanks guys :) But my instructor insists me to use threads per connection.
I got another idea, make a Session class which include:
* one thread function which will listen to the socket
* one socket to communicate with the client
* send function
* mutex for the socket

so when i need to use the session.send(msg) , the send func will compete with the session.listen() thread ,of this specific session, over the socket. This solves my problem i think.

When a client receives a msg, it will push it to the msg qeuee (which is global), and the server will alsways check if this qeuee is not empty, than it will send all the clients the msg : session.send(msgQ->pop());

Sounds ok?

Share this post


Link to post
Share on other sites
In practical situation, create thread for each client is not the best solution if you are ready for about hundreds connection. Since context switch should be considered as a large overhead of your server application when more threads created.

Share this post


Link to post
Share on other sites
I think the biggest problem with threads is that you have to lock your shared world representation, so all the threads typically just end up serialized on that lock anyway -- gaining no useful parallelism.

For the original homework question, just stick 'em all in a list, wrap a lock around the list, and when you receive a message, grab the lock, loop over the list, and forward the message to each socket in the list. This assumes you have a non-broken sockets implementation -- if it's broken, you'll probably deadlock when doing this.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!