Inter-Process Communication

Modern Unix-like operating systems, several means of inter-process communication (IPC) are available, for instance:

The Fortran 2003 ISO C interoperability features allow us to write interfaces to selected IPC mechanisms, among them are:


On POSIX-compliant operating systems, signals are used to interrupt, terminate, or control running processes. A process can react to specific signals by implementing signal handlers. For example, an application may catch SIGINT to terminate when the user presses CTRL + C. Some signal numbers for FreeBSD are shown in table 1. See the man pages for a list of all signals. The GNU Fortran provides a compiler-dependent interface to POSIX signals (not a Fortran standard).

No. Name Default Action Description
1 SIGHUP Terminate process. Terminal line hang-up.
2 SIGINT Terminate process. Interrupt program.
3 SIGQUIT Create core image. Quit program.
9 SIGKILL Terminate process. Kill program.
Table 1: Selection of signals supported by FreeBSD

A signal handler is registered by calling the signal() routine. The signal number and the handler function are passed as arguments:

! signal.f90
module handlers
    implicit none
    subroutine sigint_handler
       print *, 'Process interrupted (SIGINT), exiting ...'
    end subroutine sigint_handler
end module handlers

program main
    use :: handlers
    implicit none

    call signal(2, sigint_handler)
    print *, 'Sleeping for 30 seconds ...'
    call sleep(30)
end program main

Press CTRL + C to send SIGINT to the Fortran program. The signal handler must be an external or module routine.

Anonymous Pipes

Unix pipes allow processes to communicate with other processes without having been designed explicitly for this task. The input and output streams of processes can be chained together, providing a one-way flow of data.

Anonymous or unnamed pipes are a way of inter-process communication that let the output of one program to become the input of another. The output can be redirected by using the pipe symbol | on the command-line.

The following example program reads given values in degrees Fahrenheit (°F) from stdin and writes the converted values in degrees Celsius (°C) to stdout:

! f2c.f90
program f2c
    implicit none
    integer :: rc
    real    :: f

        read (*, *, iostat=rc) f                ! Read degrees Fahrenheit (without unit) from stdin.
        if (rc /= 0) exit                       ! Exit on input error.
        print '(f0.2, " °C")', (f - 32) * 5 / 9 ! Write degrees Celsius (with unit) to stdout.
    end do
end program f2c

After compilation, just pipe the value in degrees Fahrenheit to the Fortran program:

$ gfortran10 -o f2c f2c.f90
$ echo "60.45" | ./f2c
15.81 °C

The < symbol allows to redirect the input to come from a file, while > writes the output to a file:

$ cat fahrenheit.txt
$ ./f2c < fahrenheit.txt
-4.11 °C
23.50 °C
26.56 °C
-1.11 °C

Read the input values from file fahrenheit.txt and write the output to file celsius.txt:

$ ./f2c < fahrenheit.txt > celsius.txt
$ cat celsius.txt
-4.11 °C
23.50 °C
26.56 °C
-1.11 °C

The output of a Fortran program can be piped to other applications as well, for instance, to format the current time:

! time.f90
program time
    implicit none
    integer :: dt(8)

    call date_and_time(values=dt)
    print '(3(i0, a), i0)', dt(5), ":", dt(6), ":", dt(7), ":", dt(8)
end program time

Pipe the output of program time to FIGlet:

$ gfortran10 -o time time.f90
$ ./time | figlet -f mini
        _  _  _  _     _ __
/||_|_o|_ / \o_)|_ o/||_  /
 |  | o _)\_/o_) _)o ||_)/

Named Pipes

A further kind of pipes are named pipes, also knows as FIFO (“first in, first out”). The pipe name is simply an arbitrary file name within the file system. On Unix, named pipes can be created with mkfifo, and removed with rm or unlink.

$ mkfifo ./pipe
$ echo "Hello, World!" > ./pipe

Another process can then read from the named pipe:

$ tail -f ./pipe
Hello, World!

In Fortran, we use the read and write statements to interchange data through named pipes.