Fork

On POSIX-compliant operating systems, fork(2) from unistd.h is used to spawn a new child process which can run simultaneously with and independently of the original parent process. Expensive calculations can be moved to a background process while the main process continues.

Starting with Fortran 2003, access to fork() is possible by implementing ISO C binding interfaces to the POSIX functions fork(2) and wait(2):

! posix.f90
module posix
    use, intrinsic :: iso_c_binding, only: c_int, c_int32_t
    implicit none

    interface
        ! pid_t fork(void)
        function c_fork() bind(c, name='fork')
            import :: c_int
            integer(kind=c_int) :: c_fork
        end function c_fork

        ! int usleep(useconds_t useconds)
        function c_usleep(useconds) bind(c, name='usleep')
            import :: c_int, c_int32_t
            integer(kind=c_int32_t), value :: useconds
            integer(kind=c_int)            :: c_usleep
        end function c_usleep

        ! pid_t wait(int *stat_loc)
        function c_wait(stat_loc) bind(c, name='wait')
            import :: c_int
            integer(kind=c_int), intent(out) :: stat_loc
            integer(kind=c_int)              :: c_wait
        end function c_wait
    end interface
end module posix

The example spawns a single child process with c_fork(). The child process just runs a blocking loop:

! fork.f90
program main
    use :: posix
    implicit none
    integer :: i, pid, rc

    pid = c_fork()

    if (pid == 0) then
        ! Child process.
        print '(a)', '>>> child process running ...'
        do i = 1, 3
            ! Sleep for 1 second.
            rc = c_usleep(10**6)
            print '(">>> step ", i0, " ...")', i
        end do
        print '(a)', '>>> child process done.'
    else if (pid < 0) then
        ! Error.
        print '(a)', 'fork error'
    else
        ! Parent process.
        print '("--- waiting for child ", i0, " ...")', pid
        print '("--- child ", i0, " finished.")', c_wait(rc)
    end if
end program main

The parent process will wait until the forked child process is finished. Compile the example with:

$ gfortran10 -c posix.f90
$ gfortran10 -o fork fork.f90 posix.o

Then, run:

$ ./fork
--- waiting for child 16038 ...
>>> child process running ...
>>> step 1 ...
>>> step 2 ...
>>> step 3 ...
>>> child process done.
--- child 16038 finished.