Итак, у меня есть код с двойным проверенным решением блокировки для чтения файлов данных в многопоточном (с openmp) приложении, который выглядит примерно так:
logical, dimension(10,10) :: is_data_loaded
is_data_loaded=.false.
! Other code
subroutine load(i,j)
integer,intent(in) :: i,j ! Indexes into array is_data_loaded
if(is_data_loaded(i,j)) return
!$OMP CRITICAL(load data)
if(.not.is_data_loaded(i,j)) then
call load_single_file(i,j)
is_data_loaded(i,j) = .true.
endif
!$OMP END CRITICAL(load_data)
end subroutine
Где я обеспокоен тем, что если два потока попадают в критическую область одновременно (с одним и тем же индексом i, j), второй блокируется первым, входящим в область, но как только первый завершает работу, второй поток может начните выполнять критический блок до того, как увидите обновленный флаг is_data_loaded, и мы столкнемся с проблемой, когда два потока обновляют одни и те же данные.
Итак, во-первых, это проблема с критическими блоками opemp? Я не уверен в семантике и в том, говорит ли стандарт что-то вроде «все должно быть согласовано между потоками, прежде чем следующий поток будет запущен в критическом блоке» или нет. И если это проблема, будет ли достаточно просто обернуть чтение / запись в is_data_loaded в операторе omp atomic?