【问题标题】:Why is direct I/O file not being written to?为什么没有写入直接 I/O 文件?
【发布时间】:2021-01-28 15:56:11
【问题描述】:

我正在尝试了解直接 I/O。为此,我编写了这个小玩具代码,它只是应该打开一个文件并向其中写入一个文本字符串:

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>


int main(int argc, char **argv) {

  char thefile[64];
  int fd;
  char message[64]="jsfreowivanlsaskajght";
  sprintf(thefile, "diotestfile.dat");
  if ((fd = open(thefile,O_DIRECT | O_RDWR | O_CREAT, S_IRWXU)) == -1) {
          printf("error opening file\n");
          exit(1);
  }
  write(fd, message, 64);
  close(fd);

}

我的 Cray 和 GNU 编译命令是

cc -D'_GNU_SOURCE' diotest.c

对于英特尔来说是

cc -D'_GNU_SOURCE' -xAVX diotest.c

在所有三个编译器下,文件 diotestfile.dat 都是以正确的权限创建的,但从未向其中写入任何数据。可执行文件完成后,输出文件为空白。 O_DIRECT 是罪魁祸首(或者,更准确地说,我猜是我对O_DIRECT 的错误处理)。如果我把它拿出来,代码就可以正常工作。我在尝试使用的更复杂的代码中看到了同样的问题。我需要做些什么不同的事情?

【问题讨论】:

  • 使用O_DIRECT时,文件偏移量和读写长度通常会有对齐限制。您系统上的 open 函数的手册页有望描述详细信息,这些详细信息可能因操作系统和文件系统类型而异。
  • 最有可能 write 返回 -1 但您没有检查错误。
  • 那么什么是errno?
  • @bob.sacamento 问题是,在write 返回-1 之后,errno 是什么?也就是说,perror()strerror(errno) 返回了什么?这些是需要了解的重要功能:它们确实试图告诉你失败的原因,而不仅仅是那个无意义的 -1。
  • @bob.sacamento 系统调用的返回值是not errno。 errno 是一个特殊的其他变量;它曾经是一个预定义的全局变量。你想#include &lt;errno.h&gt;,然后,从字面上看,打电话给strerror(errno)

标签: c file io


【解决方案1】:

继续 Ian Abbot 的评论,我发现可以通过在“消息”数组中添加对齐属性来解决问题:

#define BLOCK_SIZE 4096
int bytes_to_write, block_size=BLOCK_SIZE;
bytes_to_write = ((MSG_SIZE + block_size - 1)/block_size)*block_size;
char message[bytes_to_write]  __attribute__ ((aligned(BLOCK_SIZE)));

(系统 I/O 块大小为 4096。)

这样就解决了。仍然不能声称了解正在发生的一切。如果您愿意,请随时启发我。感谢大家的cmets。

【讨论】:

    【解决方案2】:

    嗯,你需要重新考虑这个问题,因为你的程序在我的系统上运行完美,我无法从它的列表中猜出错误可能在哪里。

    • 您在发布之前是否对其进行了测试?
    • 如果程序没有写入文件,最好查看write(2) 的返回码。你做过吗?我无法检查,因为在我的系统(intel 64bit/FreeBSD)上,程序按您的预期运行。

    你的程序运行,没有输出,一个名为diotestfile.dat的文件出现在.目录中,内容为jsfreowivanlsaskajght

    lcu@europa:~$ ll diotestfile.dat 
    -rwx------  1 lcu  lcu  64  1 feb.  18:14 diotestfile.dat*
    lcu@europa:~$ cat diotestfile.dat 
    jsfreowivanlsaskajghtlcu@europa:~$ _
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-02-23
      • 2020-11-04
      • 2017-09-14
      • 2015-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-27
      相关资源
      最近更新 更多