C 使用Linux AIO,可以执行IOs操作,但也可以将垃圾写入文件
这可能看起来很傻,但是,我使用libaio(不是posixaio),我可以在文件中写入一些内容,但我也在向文件中写入额外的内容 我阅读了有关对齐要求和iocb缓冲区字段的数据类型的信息 这是代码示例(仅用于表示相关的使用部分) 输出: 这段代码确实创建了文件,并写入了预期的字符串 hello堆栈溢出到文件/tmp/someFile中 问题: 文件/tmp/someFile在预期字符串后面还包含, @^@^@^@^@^@^@^@^@^文件本身的某些部分(代码部分)可以说是垃圾 在某种程度上,我确信这是数据字段中的某个指针出错,但无法破解它C 使用Linux AIO,可以执行IOs操作,但也可以将垃圾写入文件,c,linux,pointers,io,aio,C,Linux,Pointers,Io,Aio,这可能看起来很傻,但是,我使用libaio(不是posixaio),我可以在文件中写入一些内容,但我也在向文件中写入额外的内容 我阅读了有关对齐要求和iocb缓冲区字段的数据类型的信息 这是代码示例(仅用于表示相关的使用部分) 输出: 这段代码确实创建了文件,并写入了预期的字符串 hello堆栈溢出到文件/tmp/someFile中 问题: 文件/tmp/someFile在预期字符串后面还包含, @^@^@^@^@^@^@^@^@^文件本身的某些部分(代码部分)可以说是垃圾 在某种程度上,我确信
- 如何使用aio(而不是posix)将“hello world”准确且仅写入文件
编辑2:粗心大意,我在文件中设置了更多要写入的字节数,代码对此表示尊重。简单地说,要准确地写“hw”,在iocb的bytes字段中只需要不超过2个字节。这里发生了一些事情。首先,您提到的对齐要求是512字节或4096字节,具体取决于您的底层设备。尝试512字节开始。它适用于:
someBuffer%512
并获得0。(按照代码的原样,很可能不会是这样。)根据我的经验,未能满足上述任何一项要求实际上并不会让您返回错误!相反,它将使用普通的、常规的阻塞I/O来完成I/O请求 未对齐的I/O:如果您真的、真的需要写入少量数据或以未对齐的偏移量写入,那么即使在
io_submit
接口之上,事情也会变得棘手。您需要执行对齐读取以覆盖需要写入的数据范围,然后修改内存中的数据并将对齐区域写回磁盘
例如,假设您想修改磁盘上的偏移量768到1023。您需要将偏移量512处的512字节读入缓冲区。然后,memcpy()。最后,在偏移量512处对512字节缓冲区进行写入
未初始化数据:正如其他人指出的,您尚未完全初始化正在编写的缓冲区。使用memset()
将其初始化为零,以避免写入垃圾
分配对齐指针:要满足数据缓冲区的指针要求,需要使用posix_memalign()
。例如,要分配具有512字节对齐限制的4096字节:posix_memalign(&ptr,512,4096)代码>
<强>最后,考虑是否需要这样做。< /强>即使在最好的情况下,<代码> IOSUpjiS/<代码>仍然是“块”,尽管在10到100微秒级别。使用
pread
和pwrite
的正常阻塞I/O为您的应用程序提供了许多好处。而且,如果它变得繁重,您可以将它降级到另一个线程。如果你有一个对延迟敏感的应用程序,无论如何你都需要在另一个线程中执行io_submit 您想要的字符串长度是100字节,还是可能更短?/tmp/someFile
的文件大小最终是100,对吗?@Hasturkun更短。请注意,您正在设置在somecb.aio_nbytes=100中写入100字节代码>,我假定这是您的最终文件大小。您可能正在写入缓冲区的初始化部分。编写时可能需要使用实际字符串长度。1)somecb.aio_buf=(uint64_t)someBuffer代码>:我看这里没有演员阵容。2) struct iocb*somecbs[1]代码>你不需要这个。3) 您假设缓冲区为零/空。>根据我的经验,未能满足上述任何要求实际上不会返回错误!我该如何确切地证明它?strace是否足够?是的,使用strace-T
。这将为您提供每次系统调用所花费的时间。如果您呼叫io_submit的时间超过50微秒,则可能是使用缓冲I/O。如果我的回答对您有所帮助,请接受。谢谢
aio_context_t someContext;
struct iocb somecb;
struct io_event someevents[1];
struct iocb *somecbs[1];
somefd = open("/tmp/someFile", O_RDWR | O_CREAT);
char someBuffer[4096];
... // error checks
someContext = 0; // this is necessary
io_setup(32, &someContext ); // no error checks pasted here
strcpy(someBuffer, "hello stack overflow");
memset(&somecb, 0, sizeof(somecb));
somecb.aio_fildes = somefd ;
somecb.aio_lio_opcode = IOCB_CMD_PWRITE;
somecb.aio_buf = (uint64_t)someBuffer;
somecb.aio_offset = 0;
somecb.aio_nbytes = 100; // // //
// I am avoiding the memeaign and sysconf get page part in sample paste
somecbs[0] = &somecb; // address of the solid struct, avoiding heap
// avoiding error checks for this sample listing
io_submit(someContext, 1, somecbs);
// not checking for events count or errors
io_getevents(someContext, 1, 1, someevents, NULL);