2011-01-12 75 views
2

下面的代码:在Linux(Ubuntu的9.10,与-lrt编译)的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; 
} 

做工精细,印刷

1 
1 

,但未能在OS X(10.6 0.6和10.6.5,我已经测试了两台机器):

1 
35, readerr 

这是可能的,这是由于在OS X上的一些库错误,还是我做的索姆错了吗?

+0

仅供参考,35`EAGAIN`,该规范读出 “由于系统资源的限制,该请求未排队..” – 2011-01-12 06:00:18

回答

5

你需要调用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)手册页的重要说明(重点矿):

异步I/O控制块结构由aiocbp指向和 缓冲区该结构引用的aiocbp->aio_buf构件必须 保持有效,直到操作完成。由于这个原因,使用 自动(堆栈)变量为这些对象是不鼓励

异步I/O控制缓冲区aiocbp应在调用之前清零,以避免将伪造上下文信息传递给内核。

+0

谢谢,则aio_return节省了我的一天。我意识到堆栈的缺点,但这不是问题,因为我总是等待读取完成后立即完成(无用,我知道,这是一个愚蠢的功课)。 – Pyetras 2011-01-12 06:28:31

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 = malloc的(的sizeof(结构的aiocb)); memset的(AIO,0,的sizeof(结构的aiocb));并没有帮助,那肯定是别的。 – Pyetras 2011-01-12 06:23:16