2014-02-18 99 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

相关问题