因此,我有一些带有双重检查锁定解决方案的代码,用于在多线程(使用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原子语句中就足够了吗?
发布于 2019-03-30 13:55:37
我认为代码是错误的,因为在另一个线程从critical区域设置了is_data_loaded之后,线程可能确实看不到它的更新。虽然critical区域将确保发生相应的内存刷新,但执行if(is_data_loaded(i,j)) return的线程可能看不到更新,因为此语句可能仍会看到过时的数据。
我认为需要在if(is_data_loaded(i,j)) return之前添加!$omp flush,以确保所有数据都已刷新,并使用最新数据加载is_data_loaded(i,j)。
https://stackoverflow.com/questions/55226783
复制相似问题