You can do I/O in a loop that executes in parallel, provided that:
It does not matter that the output from different threads is interleaved (program output is nondeterministic.)
You can ensure the safety of executing the loop in parallel.
Example: I/O statement in loop
C$PAR DOALL do i = 1, 10 ! Parallelized with no warning (not advisable) k = i call show ( k ) end do end subroutine show( j ) write(6,1) j 1 format('Line number ', i3, '.') end demo% f77 -silent -explicitpar -vpara t13.f demo% setenv PARALLEL 2 demo% a.out (The output displays the numbers 1 through 10, but in a different order each time.)
Example: Recursive I/O:
do i = 1, 10 <-- Parallelized with no warning ---unsafe k = i print *, list( k ) <-- list is a function that does I/O end do end function list( j ) write(6,"('Line number ', i3, '.')") j list = j end demo% f77 -silent -mt t14.f demo% setenv PARALLEL 2 demo% a.out
In the preceding example, the program may deadlock in libF77_mt and hang. Press Control-C to regain keyboard control.
There are situations where the programmer might not be aware that I/O could take place within a parallelized loop. Consider a user-supplied exception handler that prints output when it catches an arithmetic exception (like divide by zero). If a parallelized loop provokes an exception, the implicit I/O from the handler may cause I/O deadlocks and a system hang.
In general:
The library libF77_mt is MT safe, but mostly not MT hot.
You cannot do recursive (nested) I/O if you compile with -mt.
As an informal definition, an interface is MT safe if:
It can be simultaneously invoked by more than one thread of control.
The caller is not required to do any explicit synchronization before calling the function.
The interface is free of data races.
A data race occurs when the content of memory is being updated by more than one thread, and that bit of memory is not protected by a lock. The value of that bit of memory is nondeterministic--the two threads race to see who gets to update the thread (but in this case, the one who gets there last, wins).
An interface is colloquially called MT hot if the implementation has been tuned for performance advantage, using the techniques of multithreading. For some formal definitions of multithreading technology, read the Solaris Multithreaded Programming Guide.