Search code examples
fortransleepgfortranintel-fortran

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


I was making some tests with the code bellow when I faced an strange behavior in my program. When I use the call for the intrinsic subroutine "sleep" in my program nothing was written to the file testing.dat. If I removed the call for this subroutine it worked fine, the numbers were written. I tried the same code (calling the subroutine "sleep") with Intel Fortran and it worked fine as well.

It seems to me that the sleep subroutine halts in some sense the execution before the file is written with the program compiled using gfortran, behavior that does not occur using intel fortran. I'm not an computer science expert but that is my guess, does anyone else have a better one? I tried with all the flags bellow and nothing has changed:

gfortran -g file.f90 -o executable

gfortran file.f90 -o executable

gfortran -O3 file.f90 -o executable

I am using a 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

Solution

  • File output can be buffered. That means that the characters or bytes that are to be written in the external file are first gathered somewhere in memory and than written to the external file in larger chunks. That can speed-up file output. If you look at the external file i a random moment, it does not have to contain the output from all write statements that were executed, some may be in the buffers. The flush(unit) statement makes the data visible to the external processes by flushing the data. The gfortran manual for the older flush intrinsic subroutine states

    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.

    File buffering can also be typically controlled by compiler or runtime-library settings using compiler flags or environment variables. For gfortran you can find the runtime variables at https://gcc.gnu.org/onlinedocs/gfortran/Runtime.html#Runtime

    There are four variables you might be interested in:

    GFORTRAN_UNBUFFERED_ALL: Do not buffer I/O for all units
    GFORTRAN_UNBUFFERED_PRECONNECTED: Do not buffer I/O for preconnected units.
    GFORTRAN_FORMATTED_BUFFER_SIZE: Buffer size for formatted files
    GFORTRAN_UNFORMATTED_BUFFER_SIZE: Buffer size for unformatted files