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.6 и 10.6.5, я проверил его на двух машинах):
1
35, readerr
Возможно ли это, что это связано с какой -то ошибкой библиотеки на OS X, или я делаю что -то не так?
Решение
Вам нужно позвонить 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)
мужская страница (акцент на мой):
Асинхронная структура управления ввода/выводами, на которую указывают
aiocbp
и буфер, которыйaiocbp->aio_buf
Член ссылки на структуру должен оставаться действительным до завершения операции. По этой причине, Использование переменных автоматического (стека) для этих объектов обескуражено.Асинхронный буфер управления вводами/выводом
aiocbp
должно быть обнуждено доaio_read()
Позвоните, чтобы избежать передачи поддельной контекстной информации в ядро.
Другие советы
Попробуйте обнулить 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.