usleep()计算经过的时间表现得很奇怪

时间:2013-02-13 11:24:43

标签: c gettimeofday usleep

我正在使用下面的代码计算每次连续调用处理函数所经过的时间(以毫秒为单位)。当我使用usleep(1000)时,即每次呼叫之间的1ms时差是10ms,并且当我使用usleep(1000000),即1秒时,令人惊讶的是每次呼叫之间的时间间隔下降到小于1ms。以下是代码段:

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

    struct timeval start_time;
    void handler(int);

    int main()
    {
            struct timeval current_time;
            int i=0;
            gettimeofday(&start_time,0);
            gettimeofday(&current_time,0);
            printf("%012.3fms: emulationbegins\n",((current_time.tv_usec-start_time.tv_usec)/1000.0));

            while(i++<5)
            {
                    usleep(1000); // compare with usleep(1000000)
                    handler(i);
            }

            return 0;
    }

    void handler(int i)
    {
            printf("In Handler %d\n",i);
            struct timeval current_time;
            gettimeofday(&current_time,0);
            printf("%012.3fms: Handler Called\n",((current_time.tv_usec-start_time.tv_usec)/1000.0));
            return;
    }

2 个答案:

答案 0 :(得分:3)

请记住,tv_usec结构的timeval字段永远不会超过(或超过)一百万,而是会增加秒数。

您必须在计算中使用tv_sec字段。

答案 1 :(得分:2)

usleep被指定至少睡觉你给它的数量,但它可以睡得更久。它的睡眠时间几乎没有上限,因为如果有更重要的进程要运行,操作系统就不必运行你的进程。

实际上,usleep将睡眠多长时间的分辨率取决于操作系统使用的时钟。直到几年前,大多数类似unix的系统使用静态100Hz定时器(或者在一些罕见的情况下为1024Hz)来驱动这样的定时器,所以你的睡眠总是会四舍五入到最接近的10ms。

最近在一些系统上已经完成了一些工作来移除静态时钟,尽管这并没有因为需要更高分辨率的睡眠而被驱动,而是因为不断地唤醒cpu以获得静态时钟滴答对功耗不利。它可能具有提高计时器分辨率的副作用,但这反过来暴露了使用非常短暂的睡眠并且看起来行为正确的应用程序中的错误。突然在usleep / nanosleep / poll / select中有更高的超时分辨率,这些短暂的睡眠会导致应用程序在cpu上旋转,重新安排他们的睡眠时间。

我不确定今天的状态是什么,但从你的10ms看起来你的系统仍然使用100Hz时钟作为其内部定时器,或者它故意将超时速度减慢到10ms分辨率以防止应用程序破坏