Mutexes in Co-array Fortran
In the previous example, we saw how to manage simple counter state using atomic operations. For more complex state, we can use a critical section to safely access data across multiple images.
module container_mod
use iso_fortran_env
implicit none
type :: container
integer :: counters(2)[*]
end type container
contains
subroutine inc(this, name)
type(container), intent(inout) :: this
integer, intent(in) :: name
critical
this%counters(name) = this%counters(name) + 1
end critical
end subroutine inc
end module container_mod
program mutexes
use container_mod
use iso_fortran_env
implicit none
type(container) :: c
integer :: i
c%counters = 0
do i = 1, 10000
call inc(c, 1)
end do
sync all
if (this_image() == 1) then
do i = 1, 10000
call inc(c, 1)
end do
do i = 1, 10000
call inc(c, 2)
end do
print *, "Counters:", c%counters
end if
end program mutexes
In this Co-array Fortran version:
We define a
container
type that holds an array of counters as a co-array.The
inc
subroutine increments a named counter within a critical section to ensure thread safety.In the main program, we initialize the counters to zero.
We then perform increments across multiple images:
- All images increment the first counter 10000 times.
- Image 1 additionally increments the first counter another 10000 times and the second counter 10000 times.
We use
sync all
to ensure all images have completed their operations before printing the results.Finally, we print the counters from image 1.
To run the program:
$ gfortran -fcoarray=lib mutexes.f90 -o mutexes
$ ./mutexes
Counters: 20000 10000
This example demonstrates how to use critical sections in Co-array Fortran to safely manage shared state across multiple images, which is analogous to using mutexes in other languages.