通过添加额外的步骤和调试输出,我们发现我们的 linux 上的 aio 驱动程序存在问题(5.3 Carthage,2.6.18-128.el5)
我们应用的解决方案(我把它放在以防万一有人遇到同样的问题)是这样的:(
我们自己计算经过的秒数。)
1) 如果我们看到从我们返回的错误,io_getevents()
我们会报告它。完毕。
2) 如果我们看到 0 个作业完成且经过的秒数,我们计算自己超出了预期的一个,我们会报告错误。完毕。否则我们继续(我们不更改超时时间io_getevents()
)
3)如果一些工作完成了,我们分析它们res
的错误(负值),如果有任何失败的工作,我们报告它。完毕。
4)如果还有一些剩余的工作,我们重置计时器(是的,我们将再次等待“预期”时间)并继续。
使用此方法,如果io_getevents()
报告错误或任何作业报告错误,我们将报告错误。在最坏的情况下,当每个作业在整个 T-epsilon 等待时间后返回 ok 时,整个过程将需要 N * T 时间才能完成。
我希望有人会发现它有用。
祝福,
格雷格。
例子:
struct timespec tmCountStart ;
unsigned seconds_delay = SECONDS_DELAY ;
clock_gettime( CLOCK_REALTIME, &tmCountStart ) ;
while ( num_remaining_jobs > 0 )
{
struct timespec ts = { seconds_delay, 0 } ;
struct io_event events[ num_remaining_jobs ] ;
long ec ;
do
{
ec = io_getevents( ctx, num_remaining_jobs, num_remaining_jobs, &events[ 0 ], &ts ) ;
}
while( ec == -EINTR ) ;
if ( ec < 0 )
throw exception reporting error ec. cancel all remaining jobs
else if ( ec == 0 )
{
const double elapsed = count elapsed seconds from tmCountStart
seconds_delay = SECONDS_DELAY - static_cast< unsigned >( elapsed ) ;
if ( seconds_delay > SECONDS_DELAY )
throw exception reporting timeout. cancel all remaining jobs
}
else // we got some jobs back. may not all of them
{
for ( int i = 0 ; i < ec ; i++ )
if (( int64_t )events[ i ].res < 0 )
throw exception reporting failing job. cancel all remaining jobs.
num_remaining_jobs -= ec ;
if ( num_remaining_jobs > 0 )
{
clock_gettime( CLOCK_REALTIME, &tmCountStart ) ; // reset timer.
seconds_delay = SECONDS_DELAY ;
}
}
}