2

私は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。また、このセクションでアクティブになっているスレッドは1つだけであることに注意してください(aは、1つのスレッドだけでget_num_threads()入力InitializeLinesしていることを示しています)。離陸する-fopenmpとすぐに、セグメンテーション違反は発生せず、プログラムは正しく実行されます。

また、-DUSEOPENMPopenmpを使用する場合のフラグがmakefileにあることにも注意してください。それを定義していない場合、openmpアクションは実行されません。これは重要です。なぜなら、を使用せず -DUSEOPENMPにコンパイルする -fopenmp、余分なスレッドを呼び出したり、openmpの一部を使用したりしていないことを100%確信しているにもかかわらず、同じセグメンテーション違反の問題が発生するからです。

-staticさて、少し遊んでみると、コンパイルオプションとしてを取り出すと、この問題がなくなることがわかりました。私の質問は-なぜですか?なぜそれが一緒に機能しないのですか、-staticそして-fopenmpそれは私が他の方法で対処できる問題ですか?

4

1 に答える 1

3

これはglibc固有の問題です。静的リンクは、OpenMPなどのスレッド化されたプログラムではうまく機能しません。libpthread.aただし、回避策があります。直接参照されるシンボルだけでなく、アーカイブ全体をリンカに強制的にリンクさせ-Wl,--whole-archive -lpthread -Wl,--no-whole-archiveます。

システムライブラリを静的にリンクする本当に正当な理由がない限り、そうしないでください。

于 2012-06-23T08:32:35.073 に答える