【问题标题】:close() system call takes long time to finishclose() 系统调用需要很长时间才能完成
【发布时间】:2016-07-01 16:18:44
【问题描述】:

我正在使用sendfile() 在 Linux 6.4 下复制大文件来测试性能。 我的代码遵循以下逻辑,使用gcc编译

 read_fd = open (argv[1], O_RDONLY);
 fstat(read_fd, &stat_buf);
 write_fd = open (argv[2], O_WRONLY | O_CREAT, stat_buf.st_mode);

 left_to_write = stat_buf.st_size;
 while (left_to_write > 0) {
      written=sendfile (write_fd, read_fd, &offset, stat_buf.st_size);
      if (written == -1)
           return -1;
      else {
         left_to_write -= written;
         bytes_done=stat_buf.st_size-left_to_write;           
         printf("%ld bytes written, %ld bytes left to write\n", written,  left_to_write);
  }

}

     close(read_fd);
     close(write_fd);  /* this takes minutes */

sendfile() 调用非常快;我可以看到它大约每 5 秒写入 2GB 的块。

while 循环结束时,它会在close(output) 停留几分钟,然后才能成功完成。

为什么close(output) 需要这么长时间才能运行?它是在刷新缓冲区吗?我怎样才能让它更快?

【问题讨论】:

  • 只是一点点数学运算:“它大约每 5 秒写入 2GB 的块。”表示 400MB/秒。你用什么媒介?这对于 HDD 来说太快了,而对于消费级 SSD 来说仍然相当先进。文件有多大?提供更多信息,即minimal reproducible example。见How to Ask
  • 您的open 电话没有多大意义;他们应该是input = open(…);output = …something that opens a stream socket… 吗?此外,sendfile() 的参数与 BSD 上的参数不同——这是因为您的代码是伪代码还是因为 BSD 和 Linux 存在分歧? (BSD 接口:int sendfile(int fd, int s, off_t offset, off_t *len, struct sf_hdtr *hdtr, int flags); — 我特别注意到输入文件描述符(fd)在 BSD 中位于输出流套接字(s)之前。)
  • 回答我自己:Linux 的sendfile() 与 BSD (Mac OS X) 版本完全不同。 Linux 使用不同的标头(<sys/sendfile.h> 而不是 Mac OS X 上的 <sys/uio.h>),声明为 ssize_t sendfile(int out_fd, int in_fd, off_t * offset, size_t count);。因此,除非您希望将代码移植到其他系统,否则我之前的评论并不重要——如果您是,请小心!
  • 更复杂的问题是,FreeBSD sendfile() 与 Mac OS X sendfile() 不同。好好玩! (这是一个让读者找出与 Mac OS X 定义匹配的 BSD 变体(如果有的话)的练习。主要是,这是一个“程序员当心”通知——sendfile() 因系统而异。)
  • @JonathanLeffler:可能是因为sendfile 不是任何标准的一部分 :-)

标签: c linux file linux-kernel


【解决方案1】:

这是由于写回。 close(output) 必须报告任何尚未报告的写入错误;例如,它必须确保数据所需的所有块都已分配,否则报告ENOSPC

close()返回时数据不一定写入磁盘;如果你想要这个,你需要打电话给fsync()(并忍受更长的等待时间)。

另请参阅手册页的注释部分。

【讨论】:

    猜你喜欢
    • 2018-02-07
    • 2016-07-30
    • 2013-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多