使用 Gfortran 写入并使用 SLEEP() 等待后,写入的数据在文件中不可见

Written data not visible in the file after writing with Gfortran and waiting using SLEEP()

当我在我的程序中遇到一个奇怪的行为时,我正在用下面的代码进行一些测试。当我在我的程序中调用内部子例程“sleep”时,没有任何内容写入文件 testing.dat。如果我删除了对该子程序的调用,它工作正常,数字被写入。我用 Intel Fortran 尝试了相同的代码(调用子例程“sleep”),它也运行良好。

在我看来,在使用 gfortran 编译的程序写入文件之前,sleep 子例程在某种意义上停止了执行,使用 intel fortran 不会发生这种行为。我不是计算机科学专家,但这是我的猜测,还有其他人有更好的吗? 我尝试了以下所有标志,但没有任何改变:

gfortran -g file.f90 -o 可执行文件

gfortran 文件.f90 -o 可执行文件

gfortran -O3 文件.f90 -o 可执行文件

我使用的是 xubuntu 18.01 OS。

  program test
            implicit none
            integer ::       i, j, k
            open(34, file="testing.dat")
            do i=1,9999999
              do j=1,9999999
                do k=1,9999999
                    print*, i, j, k
                    write(34,'(3I8)') i, j, k
                    call sleep (1)
                end do
              end do
            end do
    end program

可以缓冲文件输出。这意味着要写入外部文件的字符或字节首先聚集在内存中的某个位置,然后以更大的块写入外部文件。即可以speed-up文件输出。如果您随机查看外部文件,它不必包含所有已执行的 write 语句的输出,有些可能在缓冲区中。 flush(unit) 语句通过刷新数据使数据对外部进程可见。旧 flush intrinsic 子例程的 gfortran 手册指出

The FLUSH intrinsic and the Fortran 2003 FLUSH statement have identical effect: they flush the runtime library's I/O buffer so that the data becomes visible to other processes. This does not guarantee that the data is committed to disk.

文件缓冲通常也可以由编译器或 runtime-library 设置使用编译器标志或环境变量来控制。对于 gfortran,您可以在 https://gcc.gnu.org/onlinedocs/gfortran/Runtime.html#Runtime

找到运行时变量

您可能对以下四个变量感兴趣:

GFORTRAN_UNBUFFERED_ALL: 不缓冲I/O所有单位
GFORTRAN_UNBUFFERED_PRECONNECTED:不缓冲预连接单元I/O。
GFORTRAN_FORMATTED_BUFFER_SIZE: 格式化文件的缓冲区大小
GFORTRAN_UNFORMATTED_BUFFER_SIZE: 未格式化文件的缓冲区大小