每(n)秒打印一次的程序

时间:2018-07-25 11:31:40

标签: c++ clock

我编写了一个程序,该程序每五秒钟将在十秒钟的时间范围内打印一个随机数(1-10)。但是似乎每五秒钟打印一个以上的随机数。有人能指出我正确的方向吗?

clock_t start;

int random;

start = clock();

while (float(clock() - start) / CLOCKS_PER_SEC <= 10.0) {
    if (fmod(float(clock() - start) / CLOCKS_PER_SEC, 5) == 0 && (float(clock() - start) / CLOCKS_PER_SEC) != 0) {
        random = rand() % 10 + 1;
        cout << random << endl;
    }
}


return 0;

2 个答案:

答案 0 :(得分:6)

编辑:我认为此答案不完整,因为它不能回答您的实际问题。现在,第一部分说明了您的方法失败的原因,第二部分是如何更好地解决问题的方法。

您正在以某种方式使用clock(),在这种情况下您要等待许多特定的时间点。由于clock()的性质和float的有限精度,您的检查基本上等于说:我们在窗口[x-eps, x+eps]中,其中x是...的倍数。 5eps通常很小,并且取决于所使用的浮点类型以及(clock() - start)的大小。增加eps的一种方法是向1e6添加一个类似(clock() - start)的常量。如果浮点数是精确的,那不会影响您的逻辑,因为1e65的倍数,但实际上它将如此。

在快速的机器上,该条件可以每5秒多次出现。在速度较慢的计算机上,每过5秒钟可能就不是真的。

实现它的正确方法如下:但是,如果您想使用轮询方法来进行此操作(就像您当前所做的那样),则必须在if块中以5 * CLOCKS_PER_SECOND开始,并将条件更改为(clock() - start) / CLOCKS_PER_SECOND >= 5


除了您遇到的clock()特有的问题外,我想提醒您,它可以测量CPU时间或滴答滴答,并且不是测量时间的可靠方法。幸运的是,在现代C ++中,我们有std::chrono

auto t = std::chrono::steady_clock::now();
auto end = t + std::chrono::seconds( 10 );
while( t < end )
{
    t += std::chrono::seconds( 5 );
    std::this_thread::sleep_until( t );
    std::cout << ( rand() % 10 + 1 ) << std::endl;
}

我还强烈建议用rand()中更现代的工具替换<random>,例如:

std::random_device rd; // Hopefully a good source of entropy; used for seeding.
std::default_random_engine gen( rd() ); // Faster pseudo-random source.
std::uniform_int_distribution<> dist( 1, 10 ); // Specify the kind of random stuff that you want.
int random = dist( gen ); // equivalent to rand() % 10 + 1.

答案 1 :(得分:5)

您的代码似乎足够快并且您的计算精度足够小,因此您可以在计算数量更改之前进行多次迭代。因此,当条件匹配时,它将一次匹配几次。

但是,这不是一个好方法,因为您正在使计算机非常努力地工作。这种等待方式将给一个处理器带来相当大的负担,有可能减慢您的计算机速度,并肯定会消耗更多功率。如果您使用的是四核台式机,那还不错,但是对于笔记本电脑而言,电池却实在是难上加难。而不是问您的计算机“是时候了吗?是时候了吗?是时候了吗?”尽可能快地相信计算机知道如何等待,并使用sleepusleepsleep_for或您正在使用的任何库调用它。有关示例,请参见here