从OS X上的文件错误中的AIO_READ
题
以下代码:
#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)
完全适用于每个异步I/O操作。根据该人页面上的注释,如果不这样做会泄漏资源,这显然也会导致您的问题。打电话后 aio_suspend
等待I/O完成,请确保致电 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)
Man Page(强调我的):
异步I/O控制块结构指向
aiocbp
和缓冲区aiocbp->aio_buf
该结构参考的成员必须保持有效,直到操作完成为止。为此原因, 不建议使用自动(堆栈)变量.异步I/O控制缓冲液
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.
不隶属于 StackOverflow