HBatalha
HBatalha

Reputation: 235

Execute / stay in the loop for a defined amount of time e.g 1 minute

I want to make a c++ program that runs a while loop for a defined amount of time and then exits the loop. Having the loop doing some stuff while running and when the time set is reached it will break out of the loop. For example have the while the loop is running it will keep printing stuff on the screen and when 1 minute has passed it will exit the loop.

#include <iostream>
#include <time.h>


using namespace std;

int main()
{

    time_t now = time(nullptr);
    tm* current_time = localtime(&now);

    int current_minute = current_time->tm_min;

    int defined_minute = current_minute + 1;

    while (current_minute < defined_minute)
    {
        current_minute = current_time->tm_min;
    }
}

I created this code and it was supposed to work but it doesn't, I tried to debug but I still don't understand why it doesn't work.

P.S. this is my first time posting a programming problem online, appreciate if someone tells me how to better put my problems in the future.

Upvotes: 3

Views: 3998

Answers (4)

mfnx
mfnx

Reputation: 3018

Use #include <chrono>

auto t0 = std::chrono::system_clock::now();
while ( (std::chrono::system_clock::now()-t0) < std::chrono::minutes{1})
{
    // do stuff
}

Upvotes: 2

NGI
NGI

Reputation: 902

Another answer could be the use of condition variable in order to cope with the ugly sleep_for(...) often used like in my first answer leading to only 98 iterations instead of 100 because of the time taken by the application/calculations ( here printing some loop number inside a stringstream ).

Condition Variables can target more than 1 thread

#include <iostream>
#include <thread>
#include <condition_variable>
#include <atomic>
#include <chrono>
#include <sstream>

//From https://en.cppreference.com/w/cpp/thread/condition_variable/wait_until

int index[2] = { 0 };
std::stringstream sstr;
std::condition_variable cv;
std::mutex cv_m;
std::atomic<bool> do_it(true);

std::mutex mut_print;

void foo(char id, int * index)
{ 
    if ( ! index ) return;

    auto new_tp = std::chrono::system_clock::now();

    while ( do_it )
    {   
        {
            std::lock_guard<std::mutex> lock(mut_print);
            sstr << "Iteration of "<< id << ": " << ++(*index) << "\n";
        }

        new_tp += std::chrono::milliseconds(10);

        while ( do_it )
        {   
            std::unique_lock<std::mutex> lk(cv_m);
            if(std::cv_status::timeout == cv.wait_until(lk,new_tp ) ) {
                break;
            }
        }
    }
}

void signals()
{
    std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    do_it = false;
    cv.notify_all();
}

int main()
{   
    std::thread t1(foo,'A',&index[0]),t2(foo,'B',&index[1]),ts(signals);

    t1.join();
    t2.join();
    ts.join();

    std::cout << sstr.str() << "\n" << std::flush;

    std::cout << "Bye\n" << std::flush;
}

coliru

Result is

Iteration of A: 1
Iteration of B: 1
Iteration of A: 2
Iteration of B: 2
...
Iteration of A: 100
Iteration of B: 100
Iteration of A: 101
Iteration of B: 101

Bye

This time we went a little bit to far with 101 iterations but this example does not pretend to execute a limited/given number of times

Upvotes: 1

Howard Hinnant
Howard Hinnant

Reputation: 218770

Here is the simplest answer:

#include <chrono>
#include <iostream>

int
main()
{
    using namespace std;
    using namespace std::chrono;
    auto finish = system_clock::now() + 1min;
    do
    {
        cout << "stuff\n";
    } while (system_clock::now() < finish);
}

This requires C++14 or C++17. If you're using C++11, substitute minutes{1} for 1min. If you're using C++03, <chrono> is not available, and you'll have to use the C API for timing, which is significantly harder to use.

Here is a video tutorial on <chrono>.

Upvotes: 3

NGI
NGI

Reputation: 902

This snippet of code needs C++11 at least and may count somewhat complex C++ objects but here is how I imaginated it

#include <iostream>
#include <future>     //std::async
#include <atomic>
#include <chrono>
#include <sstream>

int main()
{   
    int i = 0;
    std::stringstream sstr;
    std::atomic<bool> do_it(true);

    //store future so that async returns immediately
    //see Notes paragraph on https://en.cppreference.com/w/cpp/thread/async
    auto fut = std::async(std::launch::async, [&do_it]() {
                                                        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
                                                        do_it = false;
                                                    });

    //Preemtion could steal some time here...

    while ( do_it )
    {
        sstr << "Iteration: " << ++i << "\n";
        std::this_thread::sleep_for(std::chrono::milliseconds(10));
    }

    std::cout << sstr.str() << "\n" << std::flush;

    std::cout << "Bye\n" << std::flush;
}

The result is ( you can try it on online C++ compiler like coliru)

Iteration: 1
...
Iteration: 95
Iteration: 96
Iteration: 97
Iteration: 98

Bye

Hope it helps

Upvotes: 1

Related Questions