user6200763
user6200763

Reputation: 59

C++ call a function every x seconds

I am trying to run run() function every 5 seconds without stopping while() loop (parallelly). How can I do that ? Thanks in advance

    #include <iostream>
    #include <thread>
    #include <chrono>

    using namespace std;

    void run() 
    {
        this_thread::sleep_for(chrono::milliseconds(5000));

        cout << "good morning" << endl;
    }


    int main()
    {
        thread t1(run);
        t1.detach();

        while(1)
        {
            cout << "hello" << endl;

            this_thread::sleep_for(chrono::milliseconds(500));
        }

        return 0;
    }

Upvotes: 2

Views: 7916

Answers (2)

mfnx
mfnx

Reputation: 3028

In your main function, it is important to understand what each thread is doing.

  1. The main thread creates a std::thread called t1
  2. The main thread continues and detaches the thread
  3. The main thread executes your while loop in which it:
    • prints hello
    • sleeps for 0.5 seconds
  4. The main thread returns 0, your program is finished.

Any time from point 1, thread t1 sleeps for 5 seconds and then prints good morning. This happens only once! Also, as pointed out by @Fareanor, std::cout is not thread-safe, so accessing it with the main thread and thread t1 may result in a data race.

When the main thread reaches point 4 (it actually never does because your while loop is infinite), your thread t1 might have finished it's task or not. Imagine the potential problems that could occur. In most of the cases, you'll want to use std::thread::join().

To solve your problem, there are several alternatives. In the following, we will assume that the execution of the function run without the std::this_thread::sleep_for is insignificant compared to 5 seconds, as per the comment of @Landstalker. The execution time of run will then be 5 seconds plus some insignificant time.

As suggested in the comments, instead of executing the function run every 5 seconds, you could simply execute the body of run every 5 seconds by placing a while loop inside of that function:

void run() 
{
    while (true)
    {
        std::this_thread::sleep_for(std::chrono::milliseconds(5000));
        std::cout << "good morning" << std::endl;
    }
}

int main()
{
    std::thread t(run);
    t.join();
    return 0;
}

If, for some reason, you really need to execute the run function every 5 seconds as stated in your question, you could launch a wrapper function or lambda which contains the while loop:

void run() 
{
    std::this_thread::sleep_for(std::chrono::milliseconds(5000));
    std::cout << "good morning" << std::endl;
}

int main()
{
    auto exec_run = [](){ while (true) run(); };
    std::thread t(exec_run);
    t.join();
    return 0;
}

As a side note, it's better to avoid using namespace std.

Upvotes: 4

idris
idris

Reputation: 588

Just call your run function in seperate thread function like below. Is this ok for you?

void ThreadFunction()
{
    while(true) {
        run();
        this_thread::sleep_for(chrono::milliseconds(5000));
    }
}

void run() 
{
    cout << "good morning" << endl;
}


int main()
{
    thread t1(ThreadFunction);
    t1.detach();

    while(1)
    {
        cout << "hello" << endl;

        this_thread::sleep_for(chrono::milliseconds(500));
    }

    return 0;
}

Upvotes: 1

Related Questions