用nanosleep替换usleep

use*_*007 2 c usleep

我想在我的代码中用nanosleep替换过时的usleep函数:

static int timediff( struct timeval *large, struct timeval *small )
{
        return (   ( ( large->tv_sec * 1000 * 1000 ) + large->tv_usec )
                 - ( ( small->tv_sec * 1000 * 1000 ) + small->tv_usec ) );
}

struct performance_s
{
        struct timeval acquired_input;
};

performance_t *performance_new( int fieldtimeus )
{
     performance_t *perf = malloc( sizeof( performance_t ) );
     if( !perf ) return 0;

     gettimeofday( &perf->acquired_input, 0 );

     return perf;
}

performance_t *perf = 0;

int performance_get_usecs_since_frame_acquired( performance_t *perf )
{
    struct timeval now;
    gettimeofday( &now, 0 );
    return timediff( &now, &perf->acquired_input );
}


int fieldtime = videoinput_get_time_per_field( norm );


if( rtctimer ) {
    while( performance_get_usecs_since_frame_acquired( perf )
                  < ( (fieldtime*2) - (rtctimer_get_usecs( rtctimer ) / 2) ) ) {
        rtctimer_next_tick( rtctimer );
    }
} else {
    int timeleft = performance_get_usecs_since_frame_acquired( perf );
    if( timeleft < fieldtime )
        usleep( fieldtime - timeleft );
Run Code Online (Sandbox Code Playgroud)

问题:这次更换是否与使用usleep的精确计时相同(并且是正确的替代品)?

struct timespec delay = {0, ( fieldtime - timeleft )}; nanosleep(&delay, NULL);
Run Code Online (Sandbox Code Playgroud)

R..*_*R.. 8

其中一个原因usleep是过时的,即信号中断时的行为在历史系统之间是不一致的.根据您的需要,这可能意味着您的天真替换nanosleep并不是您想要的.特别nanosleep是,即使安装了信号处理程序,也会在执行任何信号处理程序时立即返回SA_RESTART.所以你可能想做类似的事情:

while (nanosleep(&delay, &delay));
Run Code Online (Sandbox Code Playgroud)

如果它被中断则保存剩余时间并在剩余时间内重新开始休眠.

还要注意nanosleep使用timespec,以纳秒为单位,而不是微秒.因此,如果您的间隔值以微秒为单位,则必须将它们缩放1000以达到纳秒.

另外,请注意,EINVAL传递小于0或大于1000000000(1秒)的纳秒值是一个错误(报告).timespec值必须"标准化",即纳秒必须在0到999999999(含)之间,并且更大的值转换为使用结构的seconds(tv_sec)字段.