我想在我的代码中用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)
其中一个原因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)字段.