Which protection method to use (mutex , readwritelock ..) on thread inner function - c++

I have a thread that is polling data from web service and then sending it to different class to handle the data. The process of that data can takes a long time, sometimes more than the timer interval that invoking the polling function inside the thread.
I would like to protect this polling function, that is while the processing of the data is in progress, don't enter the function.
My flow is like this
workerThread -> start timer -> that invoking the polling method ->
the polling method gets the data and send it to processing > mean while this polling function can be called again .

If your polling function takes longer to execute than the polling timer than in your function implementation you could attempt to lock the mutex
void pollingFunction() {
bool isLocked = mutex.tryLock(3000); //timeout if you want
if(isLocked)
{
//process the data
}
else
{
return;
}
mutex.unlock();
}

i assume you are using at least 2 threads. one is triggered by timer, the other one is handling the polling data. so the Monitor Object pattern will work for it, you need to define a queue for the polling data and define 2 condition variables (not full, not empty). if it is not full, then the polling could start and then put the data to the queue. if it is not empty then handling could retieve the data, and handle it.

Related

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.

libuv: uv_check_t and uv_prepare_t usage

I've been reading The libuv book, however the section on check and prepare watchers is incomplete so the only info i found was in uv.h:
/*
* uv_prepare_t is a subclass of uv_handle_t.
*
* Every active prepare handle gets its callback called exactly once per loop
* iteration, just before the system blocks to wait for completed i/o.
*/
and
/*
* uv_check_t is a subclass of uv_handle_t.
*
* Every active check handle gets its callback called exactly once per loop
* iteration, just after the system returns from blocking.
*/
I was wondering if there's any special usage of libuv's check and prepare watchers.
I'm writing a native node.js binding to a c++ library that needs to handle events fired from different threads, so naturally, the callbacks should be called from the main thread. I tried using uv_async_t, however libuv does not guarantee that the callback will be invoked once per every uv_async_send so this does not work for me.
That's why i decided to go with my own thread-safe event queue which i want to check periodically. So i was wondering whether using a check or prepare watcher will be ok for this purpose.
Actually, my current solution does use an uv_async_t watcher - every time i receive an event, i put it in the queue and call uv_async_send - so when the callback is finally invoked, i handle all events currently in the queue.
My concern with this approach is that many events might actually queue up until the callback is triggered and might get invalidated meanwhile (by invalidated, i mean it's become pointless to handle them at this point).
So i want to be able to check the event queue as frequently as possible - which check/prepare watchers can provide, but maybe it's an overkill to do it (and lock a mutex) on every event loop iteration?
And, more importantly, maybe they are supposed to serve some more special purpose than just securing once-per-loop-iteration callback invocation?
Thanks
You could use a prepare handle to check your queue for events, and a async handle just to wakeup the loop.
If you use only a prepare handle you could en up in the situation where the loop is blocked for i/o and nobody would process the queue until it finishes polling. The async handle would "wakeup" the loop, and the next time prepare handles run you'd process the queue.

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

C++ in Linux: In what forked-task context should a timer callback execute?

I have implemented my own Timer/Callback classes in C/C++ in Linux, wherein a process requiring a timer to fire either ONE_SHOT or PERIODICally instantiates a timer, and instantiates a callback object and associates the callback with previously created Timer object. The Callback class implements a triggered () method, and when the timer fires at the appointed timeout, the triggered () method is executed. (Nothing new in terms of functionality.) The way my Timer class works is I maintain a minheap of Timer objects and thus always know which timer to fire next. There is a timer task (TimerTask) which itself runs as a separate process (created using fork ()) and shares the memory pools from which the Timer objects and the Callback objects are created. The TimerTask has a main while (1) loop which keeps checking if the root of the Timer object minheap has a time since epoch that is LEQ the current time since epoch. If so, the timer at root has "fired."
Currently, when the timer fires, the callback is executed in the TimerTask process context. I am currently changing this behavior to run the callback processing on other tasks (send them the information that the Timer object has fired via a POSIX message queue. For example, send the message to the Timer object creating process), but my question to SO is what are the principles behind this? Executing a callback in the TimerTask context seems like a bad idea if I expect to service a large number of timers. It seems like a good idea to dispatch the callback processing over to other processes.
What are the general rules of thumb for processing the callback in one task/process over the other? My intention is to process the callback in the receiving task using a pthread like so:
void threadFunctionForTimerCallback (void* arg)
{
while (1)
{
if ((mq_receive (msg_fd, buffer, attr.mq_msgsize, NULL)) == -1)
exit (-1);
else
printf ("Message received %s\n", buffer);
}
}
Would this be a reasonable solution? But never mind the actual way of receiving the message from the TimerTask (threads or any other method, doesn't matter), any discussion and insight into the problem of assigning a task for the callback is appreciated.
There is no need to busy spin while(1) to implement a timer. One traditional and robust way of implementing timers has been using minheap as you do to organize times to expiry and then pass the time till the next timer expiry as a timeout argument to select() or epoll(). Using select() call a thread can watch for file descriptor readiness, signals and timers all at the same time.
Recent kernels support timerfd that delivers timer expiry events as file descriptor readiness for read which again can be handled using select()/epoll(). It obviates the need to maintain the minheap, however, requires a system call for each add/modify/delete a timer.
Having timer code in another process requires processes to use inter-process communication mechanisms, thereby introducing more complexity, so it can actually make the system less robust, especially when the processes communicate via shared memory and can corrupt it.
Anyway, one can use Unix domain sockets to send messages back and forth between communicating processes on the same host. Again, select()/epoll() are your best friends. Or a more high level framework can be used for message passing, such as 0MQ.

C++ Timers in Unix

We have an API that handles event timers. This API says that it uses OS callbacks to handle timed events (using select(), apparently).
The api claims this order of execution as well:
readable events
writable events
timer events
This works by creating a point to a Timer object, but passing the create function a function callback:
Something along these lines:
Timer* theTimer = Timer::Event::create(timeInterval,&Thisclass::FunctionName);
I was wondering how this worked?
The operating system is handling the timer itself, and when it sees it fired how does it actually invoke the callback? Does the callback run in a seperate thread of execution?
When I put a pthread_self() call inside the callback function (Thisclass::FunctionName) it appears to have the same thread id as the thread where theTimer is created itself! (Very confused by this)
Also: What does that priority list above mean? What is a writable event vs a readable event vs a timer event?
Any explanation of the use of select() in this scenario is also appreciated.
Thanks!
This looks like a simple wrapper around select(2). The class keeps a list of callbacks, I guess separate for read, write, and timer expiration. Then there's something like a dispatch or wait call somewhere there that packs given file descriptors into sets, calculates minimum timeout, and invokes select with these arguments. When select returns, the wrapper probably goes over read set first, invoking read callback, then write set, then looks if any of the timers have expired and invokes those callbacks. This all might happen on the same thread, or on separate threads depending on the implementation of the wrapper.
You should read up on select and poll - they are very handy.
The general term is IO demultiplexing.
A readable event means that data is available for reading on a particular file descriptor without blocking, and a writable event means that you can write to a particular file descriptor without blocking. These are most often used with sockets and pipes. See the select() manual page for details on these.
A timer event means that a previously created timer has expired. If the library is using select() or poll(), the library itself has to keep track of timers since these functions accept a single timeout. The library must calculate the time remaining until the first timer expires, and use that for the timeout parameter. Another approach is to use timer_create(), or an older variant like setitimer() or alarm() to receive notification via a signal.
You can determine which mechanism is being used at the OS layer using a tool like strace (Linux) or truss (Solaris). These tools trace the actual system calls that are being made by the program.
At a guess, the call to create() stores the function pointer somewhere. Then, when the timer goes off, it calls the function you specified via that pointer. But as this is not a Standard C++ function, you should really read the docs or look at the source to find out for sure.
Regarding your other questions, I don't see mention of a priority list, and select() is a sort of general purpose event multiplexer.
Quite likely there's a framework that works with a typical main loop, the driving force of the main loop is the select call.
select allows you to wait for a filedescriptor to become readable or writable (or for an "exception" on the filedeescriptor) or for a timeout to occur. I'd guess the library also allow you to register callbacks for doing async IO, if it's a GUI library it'll get the low primitive GUI events via a file descriptor on unixes.
To implement timer callbacks in such a loop, you just keep a priority queue of timers and process them on select timeouts or filedescriptor events.
The priority means it processes the file i/o before the timers, which in itself takes time, could result in GUI updates eventually resulting in GUI event handlers being run, or other tasks spending time servicing I/O.
The library is more or less doing
for(;;) {
timeout = calculate_min_timeout();
ret = select(...,timeout); //wait for a timeout event or filedescriptor events
if(ret > 0) {
process_readable_descriptors();
process_writable_descriptors();
}
process_timer_queue(); //scan through a timer priority queue and invoke callbacks
}
Because of the fact that the thread id inside the timer callback is the same as the creator thread I think that it is implemented somehow using signals.
When a signal is sent to a thread that thread's state is saved and the signal handler is called which then calls the event call back.
So the handler is called in the creator thread which is interrupted until the signal handler returns.
Maybe another thread waits for all timers using select() and if a timer expires it sends a signal to the thread the expired timer was created in.