C语言 用纳米睡眠代替普通睡眠

  • 本文关键字:语言 usleep
  • 更新时间 :
  • 英文 :


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

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 );

问题:这个替换是否得到与ussleep相同的精确定时(它是一个正确的替换)?

struct timespec delay = {0, ( fieldtime - timeleft )}; nanosleep(&delay, NULL);

usleep过时的原因之一是,当它被信号中断时,其行为在历史系统中是不一致的。根据您的需要,这可能意味着您用nanosleep进行的简单替换并不完全是您想要的。特别是,当任何信号处理程序被执行时,nanosleep立即返回,即使信号处理程序安装了SA_RESTART。所以你可能想这样做:

while (nanosleep(&delay, &delay));

保存被中断时的剩余时间,并在剩余时间内重新启动休眠。

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

另外,要注意传递的纳秒值小于0或大于1000000000(1秒)是错误的(由EINVAL报告)。timespec值必须"规范化",即纳秒必须在0到999999999(包括)之间,更大的值转换为使用结构的秒(tv_sec)字段。

您的潜在目标是在获得前一帧后的fieldtime微秒内休眠。clock_nanosleep()函数允许您直接执行此操作—休眠直到达到特定的绝对时间—因此它更适合您的需求。使用这个函数的样子如下:

int fieldtime = videoinput_get_time_per_field( norm );
struct timespec deadline = performance->input;
deadline.tv_nsec += fieldtime * 1000L;
deadline.tv_sec += deadline.tv_nsec / 1000000000;
deadline.tv_nsec %= 1000000000;
while (clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &deadline, NULL) && errno == EINTR)
    ;

这假定您将performance->input更改为clock_gettime(CLOCK_MONOTONIC, &performance->input)设置的struct timespec而不是gettimeofday()CLOCK_MONOTONIC时钟更适合这种情况,因为它不受系统时间更改的影响。

相关内容

  • 没有找到相关文章

最新更新