Multithreaded Web Server Flow diagram - c++

I am writing a Multi-threaded web server with 1 scheduling thread,1 queuing thread and n execution thread in C++ and it is a homework problem. I am not asking the code. I have created a flow for the server. Can you tell me if the flow is correct or not ?
main() //queuing thread
{
define sockets
create scheduling thread
create queue of n execution threads //n execution threads
accpet connection infinetly
{
insert the request in a queue
}
}
scheduling thread // scheduling thread
{
job = take each request from queue ( FCFS or SJF)
take 1 thread from queue of execution threads and assign the job request
}
Is this flow for the problem correct? I just need the direction.Thanks in advance.

Your pseudo-code looks reasonable to me.

Related

c++ server with multiple threads

I want to write a simple C++ chat server. Simplifying:
void clientThread(int sock){
// receives data on socket and sends to all other client's
//sockets which are held in a vector, when received data<0 thread is
// finished and client is removed from a vector
}
Main loop:
vector<thread> th;
while(1){
memset(&rcvAddr,0,sizeof(sockaddr_in));
sock=accept(connectSocket,NULL,(socklen_t*)&addrLength);
cout << "client connected from: " << inet_ntoa(rcvAddr.sin_addr)<< endl;
if(sock<0)
continue;
mtx.lock();
clientDescriptors.push_back(sock);
mtx.unlock();
th.pushback(thread(&server::clientThread,this,sock));
}
And I have a problem with the last line. This vector constantly grows, do you know any proper way to manage this? How to spawn these threads? Are there any implemented data structures, or something like this, to manage threads? I read about thread Pool, but I think this does not solve this problem.
One (proper) design may be :
A thread Pool which manages a connections queue
A listening thread which accepting Sockets repeatedly
a Psuedo code may be :
main:
launch thread pool
launch the listening thread
block until server is not neaded
listening thread routine:
while true
accept a client socket
build a task out of the client socket
push the task into the connection queue
the task is the actual function/function object/object which does something meaningfull with the socket, like reading it's content, write result to client, close the socket.
It is going to keep growing, because this is what you do - you create a thread for every connection. Occasionally threads exit, but you never get to removing elements from this vector, since you are not joining threads.
Best thing to do would be to join all joinable threads from the vector automatically, but to my ongoing dismay posix completely lacks this feature - you can only join one thread at a time. Posix arrogantly states that If you believe you need this functionality, you probably need to rethink your application design. - which I do not agree with. On any rate, one thing you can do is to use thread pools - they are going to help you.

Log queue in multithreaded application

I wrote a network logger which works in separate thread. The idea was to allow application push any amount of data and logger should process it separately without slowing down the main thread. The pseudocode looks like:
void LogCoroutine::runLogic()
{
mBackgroundWorker = std::thread(&LogCoroutine::logic, this);
mBackgroundWorker.detach();
}
void LogCoroutine::logic()
{
while (true)
{
_serverLogic();
_senderLogic();
std::this_thread::sleep_for(std::chrono::milliseconds(10)); // 10ms
}
}
void LogCoroutine::_senderLogic()
{
std::lock_guard<std::mutex> lock(mMutex);
while (!mMessages.empty() && !mClients.empty())
{
std::string nextMessage = mMessages.front();
mMessages.pop_front();
_sendMessage(nextMessage);
}
}
_serverLogic checks the socket for the new connections (peers) and _senderLogic processes queue with messages and send it to all connected peers.
And the last function: pushing message:
void LogCoroutine::pushMessage(const std::string& message)
{
std::lock_guard<std::mutex> lock(mMutex);
mMessages.push_back(message);
}
Everything works well when the packages send not very often. There is a cycle when application starts which logs a lot of information. And application hangs up for a 5-10 seconds, without logging it doesn't slow down.
So, where is the bottleneck of this architecture? Maybe pushing each message with mutex inside is a bad idea?
Your approach is basically polling for log events with some interval (10 ms). This approach (which is in fact busy waiting) is not very performant, since you always consume some CPU even if there are no any log messages. On another hand if new message arrives you don't notify the waiting thread.
I would propose to use some kind of blocking queue which solves both issues. Internally blocking queue has mutex and condition variable, so that consumer thread is waiting (not busy looping!) while queue is empty. I think your use case is just ideal for blocking queue. You can really easily implement your own queue based on mutex + condition variable.
Pushing each message with mutex is not a bad idea, you have to synchronize it anyway. I would just propose to get rid of polling.
See this example:
How to use work queues for producer & consumers (1 to many). Very well explained.

C++ run a task in secondary thread and expect a response on main thread

I have to run a task in background using thread in C++. Actually in code i have to send multiple HTTP request using curl and i don't want to run using Main thread as it will put main thread blocked untill task is completed. Hence I want for each http request is should be something like that :
a) a new thread is created b) send the curl req on this new thread c) once req/response is done, send response/data back to main thread
During this process i want Main thread to be free and run some other its own task. I am new to C++ and threading, please advise how to achieve this.
If you want your main thread to be notified as soon as the worker thread is done then it sounds like you need to have a message processing loop in the main thread.
I'm just thinking this can be implemented the same way as the window procedure in WinAPI. Something along these lines.
cEvent event;
while( true )
{
event = GetNextEvent();
if( event.GetType() == APPQUIT )
{
break;
}
if( event.GetType() == SENDHHPTREQUEST )
{
// Create worker thread etc.
}
else if( event.GetType() == HTTPREQUESTCOMPLETED )
{
// Process HTTP request resuts.
}
...
}
The worker thread needs a way to send events to the main thread. And of course adding, removing events from the message queue must be thread-safe, i.e. protected with mutexes. And I guess all the data required to create a request or to process results of a request needs to be somehow packaged into cEvent.
You need to use a condition variable or auto or manual reset event to notify your main thread. You get your main thread to wait for this condition variable when you've started your secondary thread, and when the secondary thread is done, it signal's the flag which lets the main thread know it's done and can continue doing what it's doing.
if you are using c++11 standard, I had to make a "main thread caller" which takes a lambda of code and schedules it to call on main thread next time the screen updates (which is always on the main thread). Internally it uses a vector of lambdas and drains it every time update is called. If there is no lambdas, update is not scheduled. I use it extensively in my iOS/Droid production code.
you can get it here:
https://github.com/radif/emjCCMainThreadCaller

Regarding threading

I am facing one problem regarding threading scenario.
I have three threads in my process. One is subsystem1 thread , second is subsystem2 thread and third one is store manager thread.
Both subsystem1 and subsystem2 thread invoke storemanager thread for making communication with database.
Can anybody help me how to call storemanager thread method or how to pass command to invoke store manager thread method from my sybsystem threads and to get the response back from store manager thread.
Need guidance in this. i am using c++ in linux.
There is no such thing as "invoking" a thread from another thread. Your three threads are running at the same time and independently of each other.
Your store manager thread acts as a worker thread that services requests from the other two threads.
When one of the subsystem threads needs to issue a database operation it sends some form of message to the store manager thread that contains the information about the function that needs to be executed. One way to implement this communication is with a thread-safe queue. The subsystem thread in this case will add a job request to a job queue.
The store manager thread monitors the job queue and executes job requests from the queue as they are added by the other threads. Jobs that are complete are removed from the queue.
Note that the subsystem threads will not block while the store manager thread performs a requested task. Instead, you have to develop a communication mechanism between the threads by which the subsystem threads can find out when a job is complete and obtain information about the result if necessary.
I recommend that you read on thread-safe data structures and synchronization primitives.
void *storeManager(void *arg)
{
printf("\nI am storeManager function\n");
pthread_exit(NULL);
}
void *subSystem(void *arg)
{
pthread_t newThread;
printf("I am subSystem function\n");
pthread_create(&newThread, NULL, storeManager, NULL);
pthread_exit(NULL);
}
int main (int argc, char *argv[])
{
pthread_t threads;
printf("In main: creating subSystem thread\n");
pthread_create(&threads, NULL, subSystem, NULL);
pthread_exit(NULL);
}

Dedicated thread (one thread per connection) with buffering capability (c/c++)

My process reads from a single queue tasks that need to be sent to several destinations.
We need to maintain order between the tasks (ie task that arrived in the queue at 00:00 needs to be sent before the task that arrived at 00:01) therefore we cannot use thread pool. Order needs to be maintained per destination.
One solution is to create a dedicated thread per destination. The main thread reads the
task from the queue and depending on the destination finds the correct thread.
This solution has a problem: if a worker thread is busy, the master thread would remain blocked, making the system slow. What I need is a new queue per thread. The master thread
shares the resources to the queues and the worker thread reads the new queues for incoming
messages...
I would like to share my thought with the SO community, and I am searching for a C/C++ solution close to me description. Is there a library that implements such model?
The design you want is fairly straightforward; I think you can probably write the code you need and get it working in an hour or two. Looking for a 3rd party library to implement this is probably overkill (unless I am misunderstanding the problem).
In particular, for each 'worker' thread, you need a FIFO data structure (e.g. std::queue), a Mutex, and a mechanism that the 'master' thread can use to signal the thread to wake up and check the data structure for new messages (e.g. a condition variable, or a semaphore, or even a socketpair that the worker blocks on reading, and the master can send a byte on to wake the worker up).
Then to send a task to a particular worker thread, the master would do something like this (pseudocode):
struct WorkerThreadData & workerThread = _workerThreads[threadIndexIWantToSendTo];
workerThread.m_mutex.Lock();
workerThread.m_incomingTasksList.push_back(theNewTaskObject);
workerThread.m_mutex.Unlock();
workerThread.m_signalMechanism.SignalThreadToWakeUp(); // make sure the worker looks at the task list!
... and each worker thread would have an event loop like this:
struct WorkerThreadData & myData = _workerThreads[myWorkerIndex];
TaskObject * taskObject;
while(1)
{
myData.m_signalMechanism.WaitForSignal(); // block until the main thread wakes me up
myData.m_mutex.Lock();
taskObject = (myData.m_incomingTasks.length() > 0) ? myData.m_incomingTasks.pop_front() : NULL;
myData.m_mutex.Unlock();
if (taskObject)
{
taskObject->DoTheWork();
delete taskObject;
}
}
This will never block the master thread (for any significant amount of time), since the Mutex is only held very briefly by anyone. In particular, the worker threads are not holding the mutex while they are working on a task object.
The "need to maintain order" all-but-directly states that you're going to be executing the tasks serially no matter how many threads you have. That being the case, you're probably best off with just one thread servicing the requests.
You could gain something if the requirement is a bit looser than that -- for example, if all the tasks for one destination need to remain in order, but there's no ordering requirement for tasks with different destinations. If this is the case, then your solution of a master queue sending tasks to an input queue for each individual thread sounds like quite a good one.
Edit:
Specifying the number of threads/mutexes dynamically is pretty easy. For example, to take the number from the command line, you could do something on this order (leaving out error and sanity checking for the moment):
std::vector<pthread_t> threads;
int num_threads = atoi(argv[1]);
threads.resize(num_threads);
for (int i=0; i<num_threads; i++)
pthread_create(&threads[i], NULL, thread_routine, NULL);