简体   繁体   中英

How to execute a while-loop for exactly 60 seconds in C++?

Does anyone know how can I run this loop for 60 seconds and then stop? Here is my code:

#include<iostream.h>
#include<conio.h>
int main()
{
    clrscr();
    int a=1;
    int b;
    cout<<"3.";
    b=a*10%7;
    while(b!=0)
    {
        cout<<a/7;
        a=b*10;
        b=a%7;
    }
    getch();
    return 0;
}

Use the <chrono> library.

#include<iostream>
#include<conio.h>
#include<chrono>

int main()
{
    clrscr();
    int a=1;
    int b;
    std::cout<<"3."; //Don't use 'using namespace std;'...
    b=a*10%7;
    std::chrono::steady_clock::timepoint start = std::chrono::steady_clock::now();
    while(b!=0)
    {
        std::cout<<a/7;
        a=b*10;
        b=a%7;
        if(std::chrono::steady_clock::now() - start > std::chrono::seconds(60)) 
            break;
    }
    getch();
    return 0;
}

Before you start the loop get the time. Add 60 seconds. Each time through the loop get the time and compare it to your target time. Has it been 60 seconds? If so, stop.

Look at http://en.cppreference.com/w/cpp/header/chrono for the C++ library header.

Try this:

for (auto start = std::chrono::steady_clock::now(), now = start; now < start + std::chrono::seconds{60}; now = std::chrono::steady_clock::now()) 
{}  

You can achieve that just insert a time check in the loop. Since C++11 you can use chrono standard library .

The idea is the one shown in the following code snippet .

I designed the function in a template in order to be more generic and show only the conditional loop with the timer.

That is:

template <std::int64_t Seconds, typename Fn, typename... Args>
void repeat_for_seconds(Fn&& fn, Args&&... args) {
  using ClockType = std::chrono::system_clock;

  // Time at the start of the function
  auto time_start = ClockType::now();

  while (std::chrono::duration_cast<std::chrono::seconds>(ClockType::now() -
                                                          time_start)
             .count() < Seconds) {
    /* execute code you want in the while loop */
  }
}

Because ideone policies the snippet has a delay of 3 seconds, but you can easily change it in the first template parameter.

Here is one working example using chrono

#include<iostream>
#include <chrono>
using namespace std;
int main()
{
    int a=1;
    int b;
    cout<<"3.";
    b=a*10%7;

    auto start = std::chrono::system_clock::now();
    auto end = std::chrono::system_clock::now();
    while((std::chrono::duration_cast<std::chrono::seconds>(end - start).count() != 60))

    {
        end = std::chrono::system_clock::now();
        cout<<"Time is"<<std::chrono::duration_cast<std::chrono::seconds>(end - start).count()<<" second"<<endl;

        cout<<a/7<<endl;
        a=b*10;
        b=a%7;
    }
}

Output (part of output)

4
Time is59 second
2
Time is60 second
8
Program ended with exit code: 0

You can make sure a loop doesn't execute subsequent times after 60 seconds with time.h!

#include <time.h>
using namespace std;

clock_t start = clock();
while ( (clock() - start)/CLOCKS_PER_SEC <= 60)
    //do stuff here

This is essentially grabbing the number of clocks at the current time and assigning it to start . After that, each iteration of the loop, it is checking if the difference between the current clock and the start clocks, divided by a factor of clocks per second for conversion, is less than or equal to your desired 60 seconds.

One way is to register a signal handler for 60 seconds.

Below is a sample program to use signal handler:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <sys/time.h>
#include <signal.h>
#include <unistd.h>

#define INTERVAL 60             // number of seconds to go off

void sigTimerStop(int signum) {
    printf("Timer ran out! Stopping timer\n");
}

void sigTimerSet(int interval) {
    printf("starting timer\n");
    struct itimerval it_val;

    it_val.it_value.tv_sec = interval;
    it_val.it_value.tv_usec = 0;
    it_val.it_interval.tv_sec = 0;
    it_val.it_interval.tv_usec = 0;

    if (signal(SIGALRM, sigTimerStop) == SIG_ERR) {
        perror("Unable to catch SIGALRM");
        exit(1);
    }
    if (setitimer(ITIMER_REAL, &it_val, NULL) == -1) {
        perror("error calling sigsetitimer()");
        exit(1);
    }
}

int main(int argc, char *argv[]) {

    sigTimerSet(INTERVAL);

    while (1) {
        // do stuff
    }
    return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM