1

I am developing a C++ application using Qt and I need to run a function asynchronously every second.

The application works this way:

  • the user start a functionallity;
  • the application call the specific function asynchronously letting the user doing something else in the meantime;
  • when the user stops the functionallity, the application stops calling the function.

For other functions I used Qt integrated SLOTS and SIGNALS, like this:

connect(timer, SIGNAL(timeout()), this, SLOT(updateView()));
timer->start(200);

but for this particular function I wanted to use only C++ functionallity like thread, mutex, future, promise and asynch.

I tried something like this:

if(cmd == start) {
    std::future<void> fn = async(std::launch::async, [](){
    // some code here
 });
}

This way, every time the user clicks start the application calls the lambda function.

Now I want that function to be called every second until the user clicks stop without avoiding him to do something else in the meantime.

Can someone help me?

ambdere
  • 71
  • 1
  • 11
  • Create a new `std::thread`, a mutex, a condition variable, and a `bool` flag. The thread locks the mutex uses wait_for() to wait 1 second on a condition variable, check the flag, call your function if it's not set, then try again. When you no longer need this to happen, lock the mutex, set the flag, notify the condition variable, and `join()` your thread. For extra credit, check the flag before and after waiting on the condition variable. Mission accomplished. – Sam Varshavchik Nov 21 '18 at 13:31
  • @SamVarshavchik thank you! I will try to implement a solution like the one you are suggesting for I want to master thread locks with mutexes and condition variables – ambdere Nov 21 '18 at 14:11

2 Answers2

2

Using std::future suppose that your code executed once and you get some result in the future. So it is not your case. Timer that you looking for may be implemented as stand-alone thread with infinite loop that periodically invoke your functor. Please look at this decision: https://stackoverflow.com/a/30425945/149818

Dewfy
  • 23,277
  • 13
  • 73
  • 121
  • 1
    Thank you! This is what I was looking for. I already wrote something like this but I forgot the existence of detach so I was able to call the fuction every second only in the main thread. – ambdere Nov 21 '18 at 13:57
0

One way ist std::thread. It is used to run another function asynchronous. Once started it finishes after returning from the function you gave it so you have to use a loop to control it.

To prevent race conditions i usually use a std::atomic variable to control that loop.

If the thread object can be called from multiple parallel threads you sould protect it with a mutex to prevent multiple parallel accesses.

One example implementation could look like this:

class MyParallelJob
{
private:
    std::thread* _thread = nullptr;
    std::atomic<bool> _threadRunning = false;

public:
    void startThread()
    {
        if(_thread == nullptr) // This condition prevents the thread from being started twice.
        {
            _threadRunning = true; // Set thread loop condition to true
            _thread = new std::thread(parallel, this); // Create thread
        }
    }

    void stopThread()
    {
        if(_thread != nullptr) // Prevents from stopping an stopped thread
        {
            _threadRunning = false; // Set thread loop condition to false
            _thread.join(); // Wait for thread to finish
            delete _thread; // Delete thread
            _thread = nullptr; // Set thread pointer to nullptr
        }
    }

    void parallel() // Function valled by thread
    {
        while(_threadRunning == true) // While thread loop condition variable is true(=> stopThread() not called)...
        {
            //Asynchronous jobs here. (eg. function call)
            sleep(1); // Sleep one second
        }

    }
}
Detonar
  • 1,409
  • 6
  • 18