我在fortran中使用openmp,在程序完成任务之前,只需尝试写入如下所示的行就会遇到段错误:
783 module Lines
784
785 character*80 eline, dline
786
787 contains
788
789 subroutine InitializeLines
790 print*, 'writing to eline'
791 write(eline,'(1x,79(''#''))')
792 print*, 'writing to dline'
793 write(dline,'(1x,79(''-''))')
794 end subroutine InitializeLines
795
796 end module Lines
在主例程中,当我尝试调用InitializeLines
时,它会在给我一个段错误之前打印出writing to eline
。现在,当我在没有-fopenmp
的情况下编译时,程序运行得非常好。另请注意,此部分中只有一个活动线程(简单地get_num_threads()
显示我只使用一个线程进入InitializeLines
)。一旦我取消-fopenmp
,就没有段错误,程序也能正确执行。
另请注意,我的makefile中有一个-DUSEOPENMP
标志,用于何时使用openmp。如果我没有定义,那么就不会发生openmp动作。这很重要,因为当我编译没有 -DUSEOPENMP
,但编译 -fopenmp
时,我得到了相同的段错误问题,即使我100%肯定我我甚至没有调用任何额外的线程或使用openmp的任何部分。
现在,通过一些游戏,我发现当我取出-static
作为编译选项时,这个问题就消失了。我的问题是 - 为什么?为什么-static
和-fopenmp
不能一起工作,这是一个我可以用其他方式解决的问题?
答案 0 :(得分:3)
这是一个glibc specific problem - 静态链接与线程程序(包括OpenMP)不兼容。但是有一种解决方法:强制链接器链接整个libpthread.a
存档,而不仅仅是直接引用的符号-Wl,--whole-archive -lpthread -Wl,--no-whole-archive
。
除非您有充分的理由静态链接系统库,否则请不要这样做。