Overview
Features
Download
Documentation
Community
Add-Ons & Services

Call functions periodically from within a class

Tips and tricks for POCO C++ Libraries users.

Call functions periodically from within a class

Postby mrallon » 03 Oct 2011, 21:53

I'm a C++ beginner (using it for a few month now), so if there is a cleaner / nicer approach for this don't hesitate to post.
All the code below is public domain (just in case someone wants to use it).

Imagine the following situation:
- You have a class C which provides access to a data structure S
- There needs to be work done on S periodically (e.g. clean a queue, increment a counter, etc.)
- C needs to have access to S constantly while the program needs access to C
- C gets created in an abstract way (e.g. a Plugin Infrastructure) so you can't be sure if the above is true for every class
- The structure S is to complex and C is required to provide access functions for it. You can't simply hand it down to another thread to do the work for you

This happened to me more then once, and I found that Poco is lacking the functionality to deal with this kind of problem out of the box.
While working with boost I solved the problem by creating a thread during the construction of the class from the class itself, I tried the same with Poco but the farest I got was a successful compile and a segmentation fault at run-time.

The template below provides a way to create a thread of a member function of the current class and call it periodically (e.g. every few seconds), or even just once if you join it right after creation.
This is the template:
Code: Select all
#ifndef INNERTHREAD_HPP
#define INNERTHREAD_HPP

#include <Poco/Runnable.h>

template <class C> class InnerThread : public Poco::Runnable {
    private:
        /** pointer to the class */
        C* pointer;
        /** pointer to the member function */
        void (C::*fpt)();
        /** whether the thread should run or not */
        bool running;
        /** timeout for each call */
        unsigned long timeout;
    public:
        ThreadFork(C* pointer, void(C::*fpt)(), unsigned long timeout) {
            this->pointer = pointer;
            this->fpt = fpt;
            this->timeout = timeout;
            this->running = true;
        }
       
        void run() {
            while (running) {
                //while running, call the function, sleep the rest
                (*pointer.*fpt)();
                usleep(timeout);
            }
        }
       
        void join() {
            this->running = false;
        }
};
#endif


What does it do?
- The constructor takes three arguments: a pointer to a class (e.g. this), a pointer to a member function of that class and an intervall
- The class is runnable and can be run using Poco::Thread
- Once it is running, it will call the function provided in the constructor
- When you're done, call a join on the object and a join on the thread (as far as I know, the class running as a thread does not get notified when a join is called, if that would be the case one join would be enough).

How to use it:
Code: Select all
//include poco + innerThread header here

class counter {
    private:
        unsigned int c;
        InnerThread<counter> innerThread;
        Poco::Thread pocoThread;
    public:
         void inc() {
            //increment c by one if you have multiple threads running this, use a locking mechanism
            this->c++;
        }
               
        //this will initialize the inner thread with a 2000 qs delay between every call of this->inc()
        counter() : innerThread(this, &counter::inc, 2000), c(0) {
            thread.start(this->tf); //this starts the poco thread using the innerThread object
        }
       
        ~counter() {
            this->tf.join(); //make the inner thread joinable
            this->t.join(); //join the poco thread
        }
};


A real life example?
Not as a source code but I've used this in a plugin for an application using poco.
Each plugin was loaded during run-time but there was no feature added to provide thread functionality for plugins.
I wrote a plugin displaying the cpu usage of the system the application was running on. Everyone familiar with linux knows that getting the cpu usage on linux takes about once second due to a small interval between accessing the data (if you want to know more, see /proc/stat and `man procfs`).
I didn't want the application to wait a whole second between calling the plugin and accessing the data, so I created a function which refreshes the data. The innerThread calls the function every 5 seconds or so and computes the current cpu usage, my initial method only returns the data and the one second waiting time is gone.
mrallon
 
Posts: 3
Joined: 27 Sep 2011, 01:25

Return to Tips & Tricks

Who is online

Users browsing this forum: No registered users and 3 guests