当我在无限循环中使用gettimeofday()时程序意外停止

时间:2017-09-25 08:02:01

标签: c linux gettimeofday

我编写了一个代码,以确保while(1)循环的每个循环花费特定的时间(在此示例中10000μS等于0.01秒)。问题是这段代码在开始时效果很好,但不到一分钟就停止了。这就像访问linux时间有限。现在,我正在初始化一个布尔变量,使这个时间计算运行一次而不是无限。由于性能随时间变化,因此计算每个循环的计算时间会很好。有没有其他方法可以实现这个目标?

void some_function(){
struct timeval tstart,tend;
while (1){
   gettimeofday (&tstart, NULL);
   ...
   Some computation
   ...
   gettimeofday (&tend, NULL);
   diff = (tend.tv_sec - tstart.tv_sec)*1000000L+(tend.tv_usec - tstart.tv_usec);
   usleep(10000-diff);
   }
}

2 个答案:

答案 0 :(得分:2)

  

来自usleep的man-page

 #include <unistd.h>

 int usleep(useconds_t usec);

usec是unsigned int,现在猜猜diff是&gt; 10000以下

 usleep(10000-diff);

答案 1 :(得分:0)

嗯,你为获得差异所做的计算是错误的:

diff = (tend.tv_sec - tstart.tv_sec)*1000000L+(tend.tv_usec - tstart.tv_usec);

您正在混合使用不同的整数类型,错过tv_usec可能是unsigned数量,您从另一个unsigned中减去并且可以溢出....之后,您将获得结果是一整秒加上4.0E09usec左右的数量。这是大约4000秒。或者一个多小时....大约。最好检查是否有一些进位,在这种情况下,增加tv_sec,然后从10000000减去tv_usec以获得正确的正值。

我不知道您用于struct timeval的实施方式,但最可能的是tv_sectime_t(这可能是64位)而{{1}通常只是一个tv_usec 32位值,因为它不会从unsigned更进一步。

让我举例说明......假设你已经过了100ms进行计算......而这恰好发生在一秒钟......你有

1000000

当你减去时,它会导致:

tstart.tv_sec = 123456789; tstart.tv_usec = 123456;
tend.tv_sec = 123456789; tend.tv_usec = 223456;  

但是假设你已经完成了计算,而第二次更改

tv_sec = 0; tv_usec = 100000;

时差再次是100毫秒,但是现在,当你计算你的表达式时,你得到的是第一部分,1000000(一整秒)但是,在减去第二部分之后,你得到tstart.tv_sec = 123456789; tstart.tv_usec = 923456; tend.tv_sec = 123456790; tend.tv_usec = 23456; (*)溢出。 这样您就可以进入23456 - 923456 =*=> 4294067296usleep(4295067296)4295s.。 我认为你没有足够的耐心等待它完成......但这可能会发生在您的程序中,具体取决于1h 11m的定义方式。

使进位工作的正确方法是对总和进行重新排序,先进行所有添加,然后进行减法。在与struct timevalsigned一起处理时强制转换为有符号整数,并防止unsigned中出现负溢出。

unsigned

被解析为

diff = (tend.tv_sec - tstart.tv_sec) * 1000000 + tstart.tv_usec - tend.tv_usec;