io_getevents возвращает меньшее количество заданий, чем запрошено, за время, меньшее времени ожидания

Я читаю 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 ) ;

Когда ес возвращается 7, ts.tv_sec = 10, ts.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

Ваша помощь очень ценится!
КСТАТИ. Я не смогу проверить почту раньше, чем через несколько часов.

0

Решение

Делая дополнительные шаги и отлаживая вывод, мы выясняем, что есть проблема с драйвером aio в нашем linux (5.3 Карфаген, 2.6.18-128.el5)

Решение, которое мы применили (я добавляю его на случай, если кто-то столкнется с той же проблемой), таково:
(Мы считаем прошедшие секунды для вызова сами.)

1) Если мы увидим ошибку, возвращенную из io_getevents() мы сообщаем об этом. СДЕЛАННЫЙ.

2) Если мы видим, что 0 заданий завершено и истекли секунды, мы считаем себя выше ожидаемого и сообщаем об ошибке. СДЕЛАННЫЙ. В противном случае мы продолжаем (мы не меняем тайм-аут на io_getevents())

3) Если некоторые работы завершены, мы анализируем их res для ошибки (отрицательное значение), и если была какая-либо неудачная работа, мы сообщаем об этом. СДЕЛАННЫЙ.

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 ;
}
}
}
1

Другие решения

Других решений пока нет …