Using Pthreads in a Mulithreaded Server - c

i am programming a Mulithreaded Client/Server between processes program which uses message queue's.
The Server will handle the message's send by the clients, and later it should give the work to a threads to continue handling their it's processes.
Every client will have a different message queue.
After making the connection of the 1st client and sending a thread to handle it
Using pthread_join doesnt allow me to to receive new connections that are on main thread,cause it's blocked how can i fix it.
Receiving New Messages in the main thread ( or other solution if possible)
Sending to threads to handle a client message's and after.
Getting back to receive new message

Very simple,
Make the threads you create detached from the main thread - means you don't need to "pthread_join" them anymore. So the main thread is getting new connections and new request for existing connections in a loop, if it's a new connection it will start new thread and if it's a request to an existing connection it's just add the request to the thread's queue (using a lock on it's mutex ofcourse).

Related

Closing concurrent server socket (TCP)

I'm making a concurrent server/client program in C using threads. Whenever a client connects, I create a new thread to handle it.
My problem is: I want to be able to close the server, from the client. With the command '..' for example. When I type '..' in the client, I want the server to close immediately.
I thought about having a global variable, that indicates wether the server should close or not. The problem is: When the thread is created to handle the client, the main thread goes back to accept(), and it cannot check that variable. So, it will only close when a new client connects.
Any ideas on how to solve this?
Thanks!
Use select() or (e)poll() or equivalent to wait for a client to connect BEFORE you then call accept() to accept the connection. Those kind of functions allow you to specify a timeout, that will allow you to stop waiting periodically to check for other conditions, like a shutdown request. On some platforms, you can even have these functions wait on not only the listening socket but also a separate pipe that you create privately for yourself, and when you want to "wake up" your waiting loop to do something, simply write a byte into that pipe, and when the loop detects that byte arriving then it can act accordingly.

server socket in a new thread

I want to create a server socket but don't want to block my main application by the "accept call". So I will create a socket in main application. using pthread mechanism I created a new thread in which I will use "accept call" in it. After creating socket in main application, I called "pthread join". Now when this thread executes, "accept call" is again blocking the main application. I checked using gdb. How I should go about this problem?
One way would be to make the main server socket descriptor as non-blocking and use select system call. When select returns and the main socket descriptor is having data, create a new thread to handle the newly accepted connection. This way you can achieve parallelism, The new connection, which was created will have it's own context and will be scheduled as and when possible even though while accept() waits for a connection.

Multi Threaded Server design

I am trying to implement a TCP server which is a part of a larger project. Basically the server should be able to maintain a TCP connection with any number of clients (a minimum of 32) and service any client that requests servicing. In our scenario the thing is that it will be assumed that once the client is connected to the server, it will never close the connection unless some sort of failure occurs (e-g the machine running the client breaks down ) and it will repeatedly request service from the server. Same is the case with all the other clients i-e each will maintain a connection with the server and perform transactions. so to sum up the server will be at the same time maintaining the connection with the clients while simultaneously serving each client as needed and should also have the ability to accept any other client connections that want to connect to the server.
Now I implemented the above functionality using the select() system call of the berkely socket API and it works fine when we have a small number of clients (say 10). But the server needs to be scaled to the highest possible level as we are implementing it on a 16 core machine. For that I looked through various multi threading design techniques e-g one thread per client etc and the best one in my opinion would be a thread pool design. Now As I was about to implement that I ran into some problems:
If I designate the main thread to accept any number of incoming connections and save each connections File descriptor in a data structure, and I have a pool of threads, how would I get the threads to poll that whether a particular client is requesting for service or not. The design is simple enough for scenarios in which client contacts the server and after getting the service it closes the connection so that we can pick a thread from a pool, service the client and then push it back into the pool for future connection handling. But when we have to service a set of clients that maintain a connection and request services intermittently, what would be the best approach to do this. All help will be much appreciated as I am really stuck in this.
Thanks.
Use pthreads, with one thread per CPU plus one extra thread.
The extra thread (the main thread) listens for new connections with the listen() system call, accepts the new connections with accept(), then determines which worker thread currently has the least number of connections, acquires a lock/mutex for that worker thread's "pending connections" FIFO queue, places the descriptor for the accepted connection onto the worker thread's "pending connections" FIFO queue, and sends a "check your queue" notification (e.g. using a pipe) to the worker thread.
The worker threads use "select()", and send/receive data to whatever connections they've accepted. If/when a worker thread receives a "check your queue" notification from the main thread it would acquire the lock/mutex for its "pending connections" FIFO queue and add any newly accepted connections to its "fd_set" list.
For 1024 connections and 16 CPUs; you might end up with one main thread waiting for new connections (but doing almost nothing as you wouldn't be expecting many new connections), and 16 worker threads handling an average of 64 connections each.
One thread per client is almost certainly the best design. Make sure you always have at least one thread blocked in accept waiting for a new connection - this means that after accept succeeds, you might need to create a new thread before proceeding if it was the last one. I've found semaphores to be a great primitive for keeping track of the need to spawn new listening threads.

Interleaved messages from multiple clients to a server

This question is related to Socket programming in C and Sleeping a worker thread in a file server.
I am very new to socket as well as pthreads and having to handle quite a large project.
I would like to know if a scenario as below is possible and how?
I have multiple clients to a server and each client sends multiple messages to the server.Each client is serviced by a task/worker thread. A client sends a message and upon receiving a reply sends the next message till it is done and closes the connection. The task thread process one request from the client, sends its reply and sleeps till it receives the next message from the same client,till the client closes connection and the thread exits.
Now, as I said multiple clients connect at the same time. Will the server process all messages from one client and then service the next or receive messages in an interleved manner as it arrives keeping connections of all 'live' clients open.
Will the server process all messages from one client and then service the next or receive messages in an interleved manner as it arrives keeping connections of all 'live' clients open.
Server process can handle multiple clients at the same time or in an interleved manner, depending you CPU and programming architecture.
Threaded programming + multi-core or multi-CPU can handle those requests at the same time. ^_^

Socket programming accept() in C

Okay I'm brand new to socket programming and my program is not behaving like I'd expect it to. In all the examples that I see of socket programming they use accept() and all the code after assumes that a connection has been made.
But my accept() is called as soon as I start the server. Is this supposed to happen? Or is the server supposed to wait for a connection before executing the rest of the program?
EDIT: Oops I forgot to mention it is a TCP connection.
I think this is what you're after.
http://www.sockets.com/winsock.htm#Accept
The main concept within winsocket programming is you're working with either blocking or non blocking sockets. Most of the time if you're using blocking sockets you can query the sockets recieve set to see if any call would result in your call to the routine being blocked..
For starting off with this UDP is easier considering its a datagram protocol. TCP on the other hand is a streaming protocol. So it's easier to think in regards to blocks of data that is sent and received.
For a server, you:
Create the socket - socket().
Bind it to an address.
You enter a loop in which you:
Listen for connection attempts
Accept and process them
It is not clear from your description whether you are doing all those steps.
There are multiple options for the 'process them' phase, depending on whether you plan to have a single-threaded single process handle one request before processing the next, or whether you plan to have a multi-threaded single process, with one thread accepting requests and creating other threads to do the processing (while the one thread waits for the next incoming connection), or whether you plan to have the process fork with the child processing the new request while the parent goes back to listening for the next request.
You are supposed to enter your acceptance loop after you have started listening for connections. Use select() to detect when a pending client connection is ready to be accepted, then call accept() to accept it.

Resources