与超时相比,io_getevents返回的请求数少于请求的数量

时间:2013-04-19 22:32:20

标签: c++ c linux ssd aio

我正在阅读SSD,请求20个异步作业。 io_getevents返回值7表示它超时。超时设置为10秒,如下所示。通话的经过时间实际上是4.89e-05秒,例如,还剩下几乎所有10秒。 问:任何人都有类似的事件吗?如果你这样做了,你找到了解决方案吗?

以下是代码的一部分:

struct timespec ts = { 10, 0 } ; /* ten seconds delay */
const long ec = io_getevents( ctx, num_jobs, num_jobs, &events[ 0 ], &ts ) ;

当ec返回7时,ts.tv_sec = 10ts.tv_nsec = 0

Linux内核:

Linux VTL80-G-1J4-823-21 2.6.18-274.18.1.el5 #1 SMP Thu Feb 9 12:20:03 EST 2012 x86_64 x86_64 x86_64 GNU/Linux

非常感谢您的帮助! BTW。我将无法在几小时内检查帖子。

1 个答案:

答案 0 :(得分:1)

通过添加额外步骤和调试输出,我们发现我们的linux上的aio驱动程序存在问题( 5.3 Carthage,2.6.18-128.el5

我们应用的解决方案(我将其放入以防万一有人遇到同样的问题)是这样的:
(我们计算自己呼叫的经过秒数。)

1)如果我们看到io_getevents()返回的错误,我们会报告错误。 DONE。

2)如果我们看到0个工作完成并且已经过了几秒钟,我们认为自己超过预期的一个我们报告错误。 DONE。否则我们继续(我们不会更改io_getevents()上的超时)

3)如果某些工作完成,我们会分析他们的res错误(负值),如果有任何失败的工作,我们会报告。 DONE。

4)如果有剩余的工作,我们重置计时器(是的,我们将再次等待'预期'时间)并继续。

使用此方法,如果io_getevents()报告错误或任何报告错误的作业,我们将报告错误。 在最坏的情况下,当每个作业在整个T-epsilon等待时间后返回正常时,整个过程将花费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 ;
        }
    }
}