2011-01-12 33 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