2011-01-12 4 views
2

Следующий код:aio_read от ошибок файла на OS X

#include <fcntl.h> 
#include <unistd.h> 
#include <stdio.h> 
#include <aio.h> 
#include <errno.h> 

int main (int argc, char const *argv[]) 
{ 
    char name[] = "abc"; 
    int fdes; 
    if ((fdes = open(name, O_RDWR | O_CREAT, 0600)) < 0) 
    printf("%d, create file", errno); 

    int buffer[] = {0, 1, 2, 3, 4, 5}; 
    if (write(fdes, &buffer, sizeof(buffer)) == 0){ 
    printf("writerr\n"); 
    } 

    struct aiocb aio; 
    int n = 2; 
    while (n--){ 
    aio.aio_reqprio = 0; 
    aio.aio_fildes = fdes; 
    aio.aio_offset = sizeof(int); 
    aio.aio_sigevent.sigev_notify = SIGEV_NONE; 

    int buffer2; 
    aio.aio_buf = &buffer2; 
    aio.aio_nbytes = sizeof(buffer2); 

    if (aio_read(&aio) != 0){ 
     printf("%d, readerr\n", errno); 
    }else{ 
     const struct aiocb *aio_l[] = {&aio}; 
     if (aio_suspend(aio_l, 1, 0) != 0){ 
     printf("%d, suspenderr\n", errno); 
     }else{ 
     printf("%d\n", *(int *)aio.aio_buf); 
     } 
    } 
    } 

    return 0; 
} 

отлично работает на Linux (Ubuntu 9.10, скомпилированные с -lrt), печать

1 
1 

, но не на OS X (10,6 +0,6 и 10.6.5, я испытал это на двух машинах):

1 
35, readerr 

возможно ли это, что это происходит из-за какой-то ошибки библиотеки на OS X, или я делаю сома Что-то не так?

+0

просто FYI, 35 'EAGAIN', спецификация гласит: "Из-за ограничений системных ресурсов, запрос был не в очередь .." –

ответ

5

Вам нужно позвонить aio_return(2) ровно один раз для каждой асинхронной операции ввода/вывода. Согласно примечанию на этой странице руководства, неспособность сделать это приведет к утечке ресурсов, и это, по-видимому, также вызывает вашу проблему. После вызова aio_suspend ждать ввода/вывода для завершения, убедитесь, что позвонить aio_return, чтобы получить число прочитанных байт, например:

const struct aiocb *aio_l[] = {&aio}; 
if (aio_suspend(aio_l, 1, 0) != 0) 
{ 
    printf("aio_suspend: %s\n", strerror(errno)); 
} 
else 
{ 
    printf("successfully read %d bytes\n", (int)aio_return(&aio)); 
    printf("%d\n", *(int *)aio.aio_buf); 
} 

несут Кроме того, в виду эти важные примечания со страницы aio_read(2) человек (курсив мой):

структура Asynchronous I/O Control Block указывает aiocbp и буфер, что aiocbp->aio_buf член, что ссылки структуры должны остаются в силе, пока операция не будет завершена. По этой причине использование переменных (стек) для этих объектов не рекомендуется. буфер управления aiocbp

асинхронного ввода/вывода должны быть обнулены перед вызовом aio_read(), чтобы избежать передачи фиктивных контекстной информации к ядру.

+0

Спасибо, aio_return спасает мой день. Я знаю о недостатках стека, но это не было проблемой, так как я всегда ждал, когда чтение закончится сразу после его начала (бесполезно, я знаю, это для немой домашней работы). – Pyetras

0

Попробуйте обнулить struct aiocb aio?

Руководство гласит:

RESTRICTIONS 
[...] 
    The asynchronous I/O control buffer aiocbp should be zeroed before the 
    aio_read() call to avoid passing bogus context information to the kernel. 
[...] 
BUGS 
    Invalid information in aiocbp->_aiocb_private may confuse the kernel. 
+0

изменено на что-то вроде AIO = таНос (SizeOf (структура aiocb)); memset (aio, 0, sizeof (struct aiocb)); и это не помогло, это должно быть что-то другое. – Pyetras