0

Let's have a class, which creates a thread and let run an infinite loop checking a que. In this thread, I would like to call periodically a function of the class (to process accumulated data from the que, for instance each 100 ms).

I've assembled a timer based on aswers https://stackoverflow.com/a/14665230/1699328 and https://stackoverflow.com/a/21058232 However, I do not know, how to call a function from the object, which created the thread. The timer is bellow:

#include <thread>

class TimerSimpleInfinite
{
public:
    template <class callable, class... arguments>
    TimerSimpleInfinite(int interval, callable&& f, arguments&&... args)
    {
        std::function<typename std::result_of<callable(arguments...)>::type()> task(std::bind(std::forward<callable>(f), std::forward<arguments>(args)...));

        execute = true;
        std::thread([this, interval, task]() 
        {
            while (execute)
            {
                task();
                std::this_thread::sleep_for(std::chrono::milliseconds(interval));
            }
        }).detach();

    }

    void Cancel()
    {
        execute = false;
    }

private:
    bool execute;
};

The idea I would like to achieve is to call the member class function like in the following snippet:

    // separated thread
    void Processor::Run()
    {
        // start timer - call member class function every 100 ms
        Timer timer(100, this, &Processor::EvaluateData);

        Data datata;
        while (sharedQueData.Dequeue(data))
        {
            // preprocess data...

            std::lock_guard<std::mutex> lock(mutex);
            mVector.insert(data);
        }
    }

    // member class function to be called every 100 ms by timer
    void Processor::EvaluateData()
    {
       std::lock_guard<std::mutex> lock(mutex);
       // do anything with mVector
    }

The program has to be compiled by VS 2013.

Community
  • 1
  • 1
Dom
  • 532
  • 1
  • 9
  • 23
  • Why don't you use a message queue, like [tbb::concurrent_queue<>](https://www.threadingbuildingblocks.org/docs/help/reference/containers_overview/concurrent_queue_cls.htm)? I mean processing the message queue without polling. – Maxim Egorushkin Feb 25 '15 at 20:31
  • @MaximEgorushkin Because the data in vector are based on time and I do not want to evaluate them immediately when they arrive... (see introduction). Nevertheless, this could work: `template Timer(int interval, Callable&& f, Object&& o, Args&&... args) { std::function task(std::bind(std::forward(f), std::forward(o), std::forward(args)...)); ` But, Is there a way to deduce type by std::result_of in std::function? – Dom Feb 26 '15 at 02:32
  • I am not sure why you deduce the result type. You do not use it, do you? – Maxim Egorushkin Feb 26 '15 at 08:05
  • Not now, but who knows ;-) and I want to know, if it is possible. BTW Do I need to `std::forward` the object as in comment above? I am not STL expert yet... – Dom Feb 26 '15 at 08:30
  • What you have looks like a worker thread. Worker threads normally ignore work item / task return values. You should accept the task as `std::function` and let the user decide what to initialize it with (lambda, bind expression, etc..). – Maxim Egorushkin Feb 26 '15 at 09:13

0 Answers0