2014-02-18 101 views
0

我試圖使用aio_write(1)函數。下面的代碼是我的程序。但是,aio_write()總是返回EINVAL。aio_write()總是失敗,出現錯誤EINVAL

我讀了EINVAL的錯誤原因:一個或多個aio_offset,aio_reqprio,aio_nbytes無效。但是,我無法弄清楚爲什麼我設置的值不正確!

任何人都可以幫忙嗎?

[更新]此代碼是可編譯和可運行的!但結果是不正確的!我認爲這是因爲buffer_out在寫入文件之前被覆蓋。有沒有更好的方法可以做到這一點?可以查詢aio_error(1),但這就像忙於等待並損害了性能。

有沒有更好的方法來避免緩衝區被覆蓋並保持速度?

#include <iostream> 
#include <cstring> 
#include <aio.h> 
#include <stdlib.h> 
#include <stdio.h> 
#include <sstream> 
#include <errno.h> 
using namespace std; 

#define true 1 
#define false 0 

int main() 
{ 
    int i = 0; 
    int offset = 0, fd_offset = 0; 
    int slen = 0; 
    char* buffer, *buffer_out; 
    int buffer_size = 30; 
    int is_first_write = true; 

    struct aiocb aio_param; 
    int fd_out = open("result.log", O_APPEND | O_RDWR);  

    buffer = (char*) malloc(buffer_size); 
    buffer_out = (char*) malloc(buffer_size); 
    memset(buffer, 0, buffer_size); 
    memset(buffer_out, 0, buffer_size); 

    for(i = 0; i < 10; i++) 
    { 
     stringstream ss; 
     ss << "LOG *****" << i << "-" << "********\n"; 
     slen = strlen(ss.str().c_str()); 
     //cout<<"written to offset: " << offset << endl; 
     //buffer is not large enough to take the current string 
     if(offset + slen > buffer_size) 
     { 
     //write the current buffer content (< 4K) into the file 
      memset(&aio_param, 0, sizeof(aio_param)); 
      aio_param.aio_fildes = fd_out; 
      aio_param.aio_offset = fd_offset; 
      while(aio_error(&aio_param) != 0 && is_first_write == false) {cout << "wait for the previous one finish" <<endl;} 
      aio_param.aio_buf = memcpy(buffer_out, buffer, buffer_size); //the buffer_out has to be written before it's copied to again! 
      aio_param.aio_nbytes = offset; 
      //aio_offset = ? should be the end of file for O_APPEND mode 
      aio_param.aio_sigevent.sigev_notify = SIGEV_NONE; 
      if(aio_write(&aio_param) == -1) 
      { 
       cout<<"ERR: aio_write()==-1"<<endl; 
       cout<<"errno:" << errno <<endl; 
       return 1; 
      }else{ 
       is_first_write = false; 
       fd_offset += offset; 
       cout<<"aio_write()" << offset << " bytes succeed at file offset " << fd_offset<<endl; 
       offset = 0; 
      // sleep(1); 
      //clean the buffer 
       memset(buffer, 0, buffer_size); 
      } 
     } 
     //write the current string to the buffer 
     memcpy(buffer + offset, ss.str().c_str(), slen); 
     offset += slen; 
    } 
    close(fd_out); 
    return 0; 

} 

不正確的結果是:

LOG *****2-******** 
LOG *****4-******** 
LOG *****4-******** 
LOG *****4-******** 
LOG *****5-******** 
LOG *****5-******** 
LOG *****6-******** 
LOG *****8-******** 

(應該是從0到8沒有任何重複。)

+0

爲什麼將'aio_offset'的賦值註釋掉了? –

+0

爲什麼你把'offset'而不是'buffer_size'放到'aio_nbytes'中? 'offset'最初爲0,'nbytes'的值爲0(我沒有檢查過),所以保證'EINVAL'。 –

+0

我用gdb來檢查,當它調用aio_write()時,偏移量不是0() – Mike

回答

1

既然你不分配的aio_param所有值(和它在堆棧上未初始化),我建議在使用之前將其歸零:

memset(&aio_param, 0, sizeof(aio_param)); 

另外,我想你可能想設置aio_offset

+0

HI @Jonathon,非常感謝!將參數設置爲0後,它適用於某個循環。但迭代4次後,報告錯誤:aio_write()20字節成功! aio_write()40字節成功! aio_write()60字節成功! aio_write()80字節成功! *** glibc detected *** ./aio_write:munmap_chunk():無效的指針:0x00000000013a6070 *** – Mike

+0

@MikeXu在發表評論時,看到錯誤信息是很痛苦的。相反,您應該編輯原始問題以包含此新信息。 –

+0

嗨@Jonathon,我更新了我的問題。它現在可以運行。但是buffer_out是過度的,導致結果不正確。 – Mike

相關問題