C 用nanosleep取代usleep

C 用nanosleep取代usleep,c,usleep,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_

我想在代码中用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 );

usleep
过时的原因之一是被信号中断时的行为在历史系统中不一致。根据您的需要,这可能意味着您用
nanosleep
进行天真的替换并不是您想要的。特别是,当执行任何信号处理程序时,
nanosleep
会立即返回,即使信号处理程序安装了
SA_RESTART
。因此,您可能需要执行以下操作:

while (nanosleep(&delay, &delay));
在中断时节省剩余时间,并在剩余时间内重新启动睡眠

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


另外,请注意,传递小于0或大于100000000(1秒)的纳秒值是一个错误(由
EINVAL
报告)
timespec
值必须“标准化”,即纳秒必须介于0和999999999(含)之间,并且转换为更大的值以使用结构的秒(
tv_sec
)字段。

您的基本目标是在获取上一帧后的
fieldtime
微秒前睡眠。
clock\u 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\u gettime(clock\u monotic,&performance->input)
设置的
struct timespec
CLOCK\u单调
时钟更适合这种情况,因为它不受系统时间变化的影响

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