C 用nanosleep取代usleep
我想在代码中用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_
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)
;